home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / guile-ii.src / guile-ii / guile-src / libguile / numbers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-17  |  82.0 KB  |  3,955 lines

  1. /*    Copyright (C) 1995 Free Software Foundation, Inc.
  2.  * 
  3.  * This program is free software; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2, or (at your option)
  6.  * any later version.
  7.  * 
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  * GNU General Public License for more details.
  12.  * 
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this software; see the file COPYING.  If not, write to
  15.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  *
  17.  * As a special exception, the Free Software Foundation gives permission
  18.  * for additional uses of the text contained in its release of GUILE.
  19.  *
  20.  * The exception is that, if you link the GUILE library with other files
  21.  * to produce an executable, this does not by itself cause the
  22.  * resulting executable to be covered by the GNU General Public License.
  23.  * Your use of that executable is in no way restricted on account of
  24.  * linking the GUILE library code into it.
  25.  *
  26.  * This exception does not however invalidate any other reasons why
  27.  * the executable file might be covered by the GNU General Public License.
  28.  *
  29.  * This exception applies only to the code released by the
  30.  * Free Software Foundation under the name GUILE.  If you copy
  31.  * code from other Free Software Foundation releases into a copy of
  32.  * GUILE, as the General Public License permits, the exception does
  33.  * not apply to the code that you add in this way.  To avoid misleading
  34.  * anyone as to the status of such modified files, you must delete
  35.  * this exception notice from them.
  36.  *
  37.  * If you write modifications of your own for GUILE, it is your choice
  38.  * whether to permit this exception to apply to your modifications.
  39.  * If you do not wish that, delete this exception notice.  
  40.  */
  41.  
  42.  
  43. #include <stdio.h>
  44. #include <math.h>
  45. #include "_scm.h"
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53. PROC (s_exact_p, "exact?", 1, 0, 0, scm_exact_p);
  54. PROC (s_integer_p, "integer?", 1, 0, 0, scm_exact_p);
  55. #ifdef __STDC__
  56. SCM
  57. scm_exact_p(SCM x)
  58. #else
  59. SCM
  60. scm_exact_p(x)
  61.      SCM x;
  62. #endif
  63. {
  64.   if INUMP(x) return BOOL_T;
  65. #ifdef BIGDIG
  66.   if (NIMP(x) && BIGP(x)) return BOOL_T;
  67. #endif
  68.   return BOOL_F;
  69. }
  70.  
  71. PROC (s_odd_p, "odd?", 1, 0, 0, scm_odd_p);
  72. #ifdef __STDC__
  73. SCM
  74. scm_odd_p(SCM n)
  75. #else
  76. SCM
  77. scm_odd_p(n)
  78.      SCM n;
  79. #endif
  80. {
  81. #ifdef BIGDIG
  82.   if NINUMP(n) {
  83.     ASSERT(NIMP(n) && BIGP(n), n, ARG1, s_odd_p);
  84.     return (1 & BDIGITS(n)[0]) ? BOOL_T : BOOL_F;
  85.   }
  86. #else
  87.   ASSERT(INUMP(n), n, ARG1, s_odd_p);
  88. #endif
  89.   return (4 & (int)n) ? BOOL_T : BOOL_F;
  90. }
  91.  
  92. PROC (s_even_p, "even?", 1, 0, 0, scm_even_p);
  93. #ifdef __STDC__
  94. SCM
  95. scm_even_p(SCM n)
  96. #else
  97. SCM
  98. scm_even_p(n)
  99.      SCM n;
  100. #endif
  101. {
  102. #ifdef BIGDIG
  103.   if NINUMP(n) {
  104.     ASSERT(NIMP(n) && BIGP(n), n, ARG1, s_even_p);
  105.     return (1 & BDIGITS(n)[0]) ? BOOL_F : BOOL_T;
  106.   }
  107. #else
  108.   ASSERT(INUMP(n), n, ARG1, s_even_p);
  109. #endif
  110.   return (4 & (int)n) ? BOOL_F : BOOL_T;
  111. }
  112.  
  113. PROC (s_abs, "abs", 1, 0, 0, scm_abs);
  114. #ifdef __STDC__
  115. SCM
  116. scm_abs(SCM x)
  117. #else
  118. SCM
  119. scm_abs(x)
  120.      SCM x;
  121. #endif
  122. {
  123. #ifdef BIGDIG
  124.   if NINUMP(x) {
  125.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_abs);
  126.     if (TYP16(x)==tc16_bigpos) return x;
  127.     return scm_copybig(x, 0);
  128.   }
  129. #else
  130.   ASSERT(INUMP(x), x, ARG1, s_abs);
  131. #endif
  132.   if (INUM(x) >= 0) return x;
  133.   x = -INUM(x);
  134.   if (!POSFIXABLE(x))
  135. #ifdef BIGDIG
  136.     return scm_long2big(x);
  137. #else
  138.   scm_wta(MAKINUM(-x), (char *)OVFLOW, s_abs);
  139. #endif
  140.   return MAKINUM(x);
  141. }
  142.  
  143. PROC (s_quotient, "quotient", 2, 0, 0, scm_quotient);
  144. #ifdef __STDC__
  145. SCM
  146. scm_quotient(SCM x, SCM y)
  147. #else
  148. SCM
  149. scm_quotient(x, y)
  150.      SCM x;
  151.      SCM y;
  152. #endif
  153. {
  154.   register long z;
  155. #ifdef BIGDIG
  156.   if NINUMP(x) {
  157.     long w;
  158.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_quotient);
  159.     if NINUMP(y) {
  160.       ASRTGO(NIMP(y) && BIGP(y), bady);
  161.       return scm_divbigbig(BDIGITS(x),
  162.                NUMDIGS(x),
  163.                BDIGITS(y),
  164.                NUMDIGS(y),
  165.                BIGSIGN(x) ^ BIGSIGN(y),
  166.                2);
  167.     }
  168.     z = INUM(y);
  169.     ASRTGO(z, ov);
  170.     if (1==z) return x;
  171.     if (z < 0) z = -z;
  172.     if (z < BIGRAD) {
  173.       w = scm_copybig(x, BIGSIGN(x) ? (y>0) : (y<0));
  174.       scm_divbigdig(BDIGITS(w), NUMDIGS(w), (BIGDIG)z);
  175.       return scm_normbig(w);
  176.     }
  177. #ifndef DIGSTOOBIG
  178.     w = scm_pseudolong(z);
  179.     return scm_divbigbig(BDIGITS(x), NUMDIGS(x), (BIGDIG *)&w, DIGSPERLONG,
  180.              BIGSIGN(x) ? (y>0) : (y<0), 2);
  181. #else
  182.     { BIGDIG zdigs[DIGSPERLONG];
  183.       scm_longdigs(z, zdigs);
  184.       return scm_divbigbig(BDIGITS(x), NUMDIGS(x), zdigs, DIGSPERLONG,
  185.                BIGSIGN(x) ? (y>0) : (y<0), 2);
  186.     }
  187. #endif
  188.   }
  189.   if NINUMP(y) {
  190. # ifndef RECKLESS
  191.     if (!(NIMP(y) && BIGP(y)))
  192.     bady: scm_wta(y, (char *)ARG2, s_quotient);
  193. # endif
  194.     return INUM0;
  195.   }
  196. #else
  197.   ASSERT(INUMP(x), x, ARG1, s_quotient);
  198.   ASSERT(INUMP(y), y, ARG2, s_quotient);
  199. #endif
  200.   if ((z = INUM(y))==0)
  201.     ov: scm_wta(y, (char *)OVFLOW, s_quotient);
  202.   z = INUM(x)/z;
  203. #ifdef BADIVSGNS
  204.   {
  205. #if (__TURBOC__==1)
  206.     long t = ((y<0) ? -INUM(x) : INUM(x))%INUM(y);
  207. #else
  208.     long t = INUM(x)%INUM(y);
  209. #endif
  210.     if (t==0) ;
  211.     else if (t < 0)
  212.       if (x < 0) ;
  213.       else z--;
  214.     else if (x < 0) z++;
  215.   }
  216. #endif
  217.   if (!FIXABLE(z))
  218. #ifdef BIGDIG
  219.     return scm_long2big(z);
  220. #else
  221.   scm_wta(x, (char *)OVFLOW, s_quotient);
  222. #endif
  223.   return MAKINUM(z);
  224. }
  225.  
  226. PROC (s_remainder, "remainder", 2, 0, 0, scm_remainder);
  227. #ifdef __STDC__
  228. SCM
  229. scm_remainder(SCM x, SCM y)
  230. #else
  231. SCM
  232. scm_remainder(x, y)
  233.      SCM x;
  234.      SCM y;
  235. #endif
  236. {
  237.   register long z;
  238. #ifdef BIGDIG
  239.   if NINUMP(x) {
  240.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_remainder);
  241.     if NINUMP(y) {
  242.       ASRTGO(NIMP(y) && BIGP(y), bady);
  243.       return scm_divbigbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  244.                BIGSIGN(x), 0);
  245.     }
  246.     if (!(z = INUM(y))) goto ov;
  247.     return scm_divbigint(x, z, BIGSIGN(x), 0);
  248.   }
  249.   if NINUMP(y) {
  250. # ifndef RECKLESS
  251.     if (!(NIMP(y) && BIGP(y)))
  252.     bady: scm_wta(y, (char *)ARG2, s_remainder);
  253. # endif
  254.     return x;
  255.   }
  256. #else
  257.   ASSERT(INUMP(x), x, ARG1, s_remainder);
  258.   ASSERT(INUMP(y), y, ARG2, s_remainder);
  259. #endif
  260.   if (!(z = INUM(y)))
  261.     ov: scm_wta(y, (char *)OVFLOW, s_remainder);
  262. #if (__TURBOC__==1)
  263.   if (z < 0) z = -z;
  264. #endif
  265.   z = INUM(x)%z;
  266. #ifdef BADIVSGNS
  267.   if (!z) ;
  268.   else if (z < 0)
  269.     if (x < 0) ;
  270.     else z += INUM(y);
  271.   else if (x < 0) z -= INUM(y);
  272. #endif
  273.   return MAKINUM(z);
  274. }
  275.  
  276. PROC (s_modulo, "modulo", 2, 0, 0, scm_modulo);
  277. #ifdef __STDC__
  278. SCM
  279. scm_modulo(SCM x, SCM y)
  280. #else
  281. SCM
  282. scm_modulo(x, y)
  283.      SCM x;
  284.      SCM y;
  285. #endif
  286. {
  287.   register long yy, z;
  288. #ifdef BIGDIG
  289.   if NINUMP(x) {
  290.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_modulo);
  291.     if NINUMP(y) {
  292.       ASRTGO(NIMP(y) && BIGP(y), bady);
  293.       return scm_divbigbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  294.                BIGSIGN(y), (BIGSIGN(x) ^ BIGSIGN(y)) ? 1 : 0);
  295.     }
  296.     if (!(z = INUM(y))) goto ov;
  297.     return scm_divbigint(x, z, y < 0, (BIGSIGN(x) ? (y > 0) : (y < 0)) ? 1 : 0);
  298.   }
  299.   if NINUMP(y) {
  300. # ifndef RECKLESS
  301.     if (!(NIMP(y) && BIGP(y)))
  302.     bady: scm_wta(y, (char *)ARG2, s_modulo);
  303. # endif
  304.     return (BIGSIGN(y) ? (x>0) : (x<0)) ? scm_sum(x, y) : x;
  305.   }
  306. #else
  307.   ASSERT(INUMP(x), x, ARG1, s_modulo);
  308.   ASSERT(INUMP(y), y, ARG2, s_modulo);
  309. #endif
  310.   if (!(yy = INUM(y)))
  311.     ov: scm_wta(y, (char *)OVFLOW, s_modulo);
  312. #if (__TURBOC__==1)
  313.   z = INUM(x);
  314.   z = ((yy<0) ? -z : z)%yy;
  315. #else
  316.   z = INUM(x)%yy;
  317. #endif
  318.   return MAKINUM(((yy<0) ? (z>0) : (z<0)) ? z+yy : z);
  319. }
  320.  
  321. PROC1 (s_gcd, "gcd", tc7_asubr, scm_gcd);
  322. #ifdef __STDC__
  323. SCM
  324. scm_gcd(SCM x, SCM y)
  325. #else
  326. SCM
  327. scm_gcd(x, y)
  328.      SCM x;
  329.      SCM y;
  330. #endif
  331. {
  332.   register long u, v, k, t;
  333.   if UNBNDP(y) return UNBNDP(x) ? INUM0 : x;
  334.  tailrec:
  335. #ifdef BIGDIG
  336.   if NINUMP(x) {
  337.   big_gcd:
  338.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_gcd);
  339.     if BIGSIGN(x) x = scm_copybig(x, 0);
  340.   newy:
  341.     if NINUMP(y) {
  342.       ASSERT(NIMP(y) && BIGP(y), y, ARG2, s_gcd);
  343.       if BIGSIGN(y) y = scm_copybig(y, 0);
  344.       switch (scm_bigcomp(x, y)) {
  345.       case -1:
  346.       swaprec: t = scm_remainder(x, y); x = y; y = t; goto tailrec;
  347.       case  0: return x;
  348.       case  1: y = scm_remainder(y, x); goto newy;
  349.       }
  350.       /* instead of the switch, we could just return scm_gcd(y, scm_modulo(x, y)); */
  351.     }
  352.     if (INUM0==y) return x; goto swaprec;
  353.   }
  354.   if NINUMP(y) { t=x; x=y; y=t; goto big_gcd;}
  355. #else
  356.   ASSERT(INUMP(x), x, ARG1, s_gcd);
  357.   ASSERT(INUMP(y), y, ARG2, s_gcd);
  358. #endif
  359.   u = INUM(x);
  360.   if (u<0) u = -u;
  361.   v = INUM(y);
  362.   if (v<0) v = -v;
  363.   else if (0==v) goto getout;
  364.   if (0==u) {u = v; goto getout;}
  365.   for (k = 1;!(1 & ((int)u|(int)v));k <<= 1, u >>= 1, v >>= 1);
  366.   if (1 & (int)u) t = -v;
  367.   else {
  368.     t = u;
  369.   b3:
  370.     t = SRS(t, 1);
  371.   }
  372.   if (!(1 & (int)t)) goto b3;
  373.   if (t>0) u = t;
  374.   else v = -t;
  375.   if ((t = u-v)) goto b3;
  376.   u = u*k;
  377.  getout:
  378.   if (!POSFIXABLE(u))
  379. #ifdef BIGDIG
  380.     return scm_long2big(u);
  381. #else
  382.   scm_wta(x, (char *)OVFLOW, s_gcd);
  383. #endif
  384.   return MAKINUM(u);
  385. }
  386.  
  387. PROC1 (s_lcm, "lcm", tc7_asubr, scm_lcm);
  388. #ifdef __STDC__
  389. SCM
  390. scm_lcm(SCM n1, SCM n2)
  391. #else
  392. SCM
  393. scm_lcm(n1, n2)
  394.      SCM n1;
  395.      SCM n2;
  396. #endif
  397. {
  398.   SCM d;
  399.   if UNBNDP(n2) {
  400.     n2 = MAKINUM(1L);
  401.     if UNBNDP(n1) return n2;
  402.   }
  403.   d = scm_gcd(n1, n2);
  404.   if (INUM0==d) return d;
  405.   return scm_abs(scm_product(n1, scm_quotient(n2, d)));
  406. }
  407.  
  408. #ifndef BIGDIG
  409. # ifndef FLOATS
  410. #  define long2num MAKINUM
  411. # endif
  412. #endif
  413.  
  414. #ifndef long2num
  415. PROC1 (s_logand, "logand", tc7_asubr, scm_logand);
  416. #ifdef __STDC__
  417. SCM
  418. scm_logand(SCM n1, SCM n2)
  419. #else
  420. SCM
  421. scm_logand(n1, n2)
  422.      SCM n1;
  423.      SCM n2;
  424. #endif
  425. {
  426.   return scm_long2num(scm_num2long(n1, (char *)ARG1, s_logand)
  427.               & scm_num2long(n2, (char *)ARG2, s_logand));
  428. }
  429.  
  430. PROC1 (s_logior, "logior", tc7_asubr, scm_logior);
  431. #ifdef __STDC__
  432. SCM
  433. scm_logior(SCM n1, SCM n2)
  434. #else
  435. SCM
  436. scm_logior(n1, n2)
  437.      SCM n1;
  438.      SCM n2;
  439. #endif
  440. {
  441.   return scm_long2num(scm_num2long(n1, (char *)ARG1, s_logior)
  442.               | scm_num2long(n2, (char *)ARG2, s_logior));
  443. }
  444.  
  445. PROC1 (s_logxor, "logxor", tc7_asubr, scm_logxor);
  446. #ifdef __STDC__
  447. SCM
  448. scm_logxor(SCM n1, SCM n2)
  449. #else
  450. SCM
  451. scm_logxor(n1, n2)
  452.      SCM n1;
  453.      SCM n2;
  454. #endif
  455. {
  456.   return scm_long2num(scm_num2long(n1, (char *)ARG1, s_logxor)
  457.               ^ scm_num2long(n2, (char *)ARG2, s_logxor));
  458. }
  459.  
  460. PROC (s_logtest, "logtest", 2, 0, 0, scm_logtest);
  461. #ifdef __STDC__
  462. SCM
  463. scm_logtest(SCM n1, SCM n2)
  464. #else
  465. SCM
  466. scm_logtest(n1, n2)
  467.      SCM n1;
  468.      SCM n2;
  469. #endif
  470. {
  471.   return ((scm_num2long (n1, (char *)ARG1, s_logtest)
  472.        & scm_num2long (n2, (char *)ARG2, s_logtest))
  473.       ? BOOL_T : BOOL_F);
  474. }
  475.  
  476.  
  477. PROC (s_logbit_p, "logbit?", 2, 0, 0, scm_logbit_p);
  478. #ifdef __STDC__
  479. SCM
  480. scm_logbit_p(SCM n1, SCM n2)
  481. #else
  482. SCM
  483. scm_logbit_p(n1, n2)
  484.      SCM n1;
  485.      SCM n2;
  486. #endif
  487. {
  488.   return (((1 << scm_num2long (n1, (char *)ARG1, s_logtest))
  489.        & scm_num2long (n2, (char *)ARG2, s_logtest))
  490.       ? BOOL_T : BOOL_F);
  491. }
  492.  
  493. #else
  494.  
  495. PROC1 (s_logand, "logand", tc7_asubr, scm_logand);
  496. #ifdef __STDC__
  497. SCM
  498. scm_logand(SCM n1, SCM n2)
  499. #else
  500. SCM
  501. scm_logand(n1, n2)
  502.      SCM n1;
  503.      SCM n2;
  504. #endif
  505. {
  506.   ASSERT(INUMP(n1), n1, ARG1, s_logand);
  507.   ASSERT(INUMP(n2), n2, ARG2, s_logand);
  508.   return MAKINUM(INUM(n1) & INUM(n2));
  509. }
  510.  
  511. PROC1 (s_logior, "logior", tc7_asubr, scm_logior);
  512. #ifdef __STDC__
  513. SCM
  514. scm_logior(SCM n1, SCM n2)
  515. #else
  516. SCM
  517. scm_logior(n1, n2)
  518.      SCM n1;
  519.      SCM n2;
  520. #endif
  521. {
  522.   ASSERT(INUMP(n1), n1, ARG1, s_logior);
  523.   ASSERT(INUMP(n2), n2, ARG2, s_logior);
  524.   return MAKINUM(INUM(n1) | INUM(n2));
  525. }
  526.  
  527. PROC1 (s_logxor, "logxor", tc7_asubr, scm_logxor);
  528. #ifdef __STDC__
  529. SCM
  530. scm_logxor(SCM n1, SCM n2)
  531. #else
  532. SCM
  533. scm_logxor(n1, n2)
  534.      SCM n1;
  535.      SCM n2;
  536. #endif
  537. {
  538.   ASSERT(INUMP(n1), n1, ARG1, s_logxor);
  539.   ASSERT(INUMP(n2), n2, ARG2, s_logxor);
  540.   return MAKINUM(INUM(n1) ^ INUM(n2));
  541. }
  542.  
  543. PROC (s_logtest, "logtest", 2, 0, 0, scm_logtest);
  544. #ifdef __STDC__
  545. SCM
  546. scm_logtest(SCM n1, SCM n2)
  547. #else
  548. SCM
  549. scm_logtest(n1, n2)
  550.      SCM n1;
  551.      SCM n2;
  552. #endif
  553. {
  554.   ASSERT(INUMP(n1), n1, ARG1, s_logtest);
  555.   ASSERT(INUMP(n2), n2, ARG2, s_logtest);
  556.   return (INUM(n1) & INUM(n2)) ? BOOL_T : BOOL_F;
  557. }
  558.  
  559. PROC (s_logbit_p, "logbit?", 2, 0, 0, scm_logbit_p);
  560. #ifdef __STDC__
  561. SCM
  562. scm_logbit_p(SCM n1, SCM n2)
  563. #else
  564. SCM
  565. scm_logbit_p(n1, n2)
  566.      SCM n1;
  567.      SCM n2;
  568. #endif
  569. {
  570.   ASSERT(INUMP(n1) && INUM(n1) >= 0, n1, ARG1, s_logbit_p);
  571.   ASSERT(INUMP(n2), n2, ARG2, s_logbit_p);
  572.   return ((1 << INUM(n1)) & INUM(n2)) ? BOOL_T : BOOL_F;
  573. }
  574. #endif
  575.  
  576. PROC (s_lognot, "lognot", 1, 0, 0, scm_lognot);
  577. #ifdef __STDC__
  578. SCM
  579. scm_lognot(SCM n)
  580. #else
  581. SCM
  582. scm_lognot(n)
  583.      SCM n;
  584. #endif
  585. {
  586.   ASSERT(INUMP(n), n, ARG1, s_lognot);
  587.   return scm_difference(MAKINUM(-1L), n);
  588. }
  589.  
  590. PROC (s_integer_expt, "integer-expt", 2, 0, 0, scm_integer_expt);
  591. #ifdef __STDC__
  592. SCM
  593. scm_integer_expt(SCM z1, SCM z2)
  594. #else
  595. SCM
  596. scm_integer_expt(z1, z2)
  597.      SCM z1;
  598.      SCM z2;
  599. #endif
  600. {
  601.   SCM acc = MAKINUM(1L);
  602. #ifdef BIGDIG
  603.   if (INUM0==z1 || acc==z1) return z1;
  604.   else if (MAKINUM(-1L)==z1) return BOOL_F==scm_even_p(z2)?z1:acc;
  605. #endif
  606.   ASSERT(INUMP(z2), z2, ARG2, s_integer_expt);
  607.   z2 = INUM(z2);
  608.   if (z2 < 0) {
  609.     z2 = -z2;
  610.     z1 = scm_divide(z1, SCM_UNDEFINED);
  611.   }
  612.   while(1) {
  613.     if (0==z2) return acc;
  614.     if (1==z2) return scm_product(acc, z1);
  615.     if (z2 & 1) acc = scm_product(acc, z1);
  616.     z1 = scm_product(z1, z1);
  617.     z2 >>= 1;
  618.   }
  619. }
  620.  
  621. PROC (s_ash, "ash", 2, 0, 0, scm_ash);
  622. #ifdef __STDC__
  623. SCM
  624. scm_ash(SCM n, SCM cnt)
  625. #else
  626. SCM
  627. scm_ash(n, cnt)
  628.      SCM n;
  629.      SCM cnt;
  630. #endif
  631. {
  632.   SCM res = INUM(n);
  633.   ASSERT(INUMP(cnt), cnt, ARG2, s_ash);
  634. #ifdef BIGDIG
  635.   if(cnt < 0) {
  636.     res = scm_integer_expt(MAKINUM(2), MAKINUM(-INUM(cnt)));
  637.     if (NFALSEP(scm_negative_p(n)))
  638.       return scm_sum(MAKINUM(-1L), scm_quotient(scm_sum(MAKINUM(1L), n), res));
  639.     else return scm_quotient(n, res);
  640.   }
  641.   else return scm_product(n, scm_integer_expt(MAKINUM(2), cnt));
  642. #else
  643.   ASSERT(INUMP(n), n, ARG1, s_ash);
  644.   cnt = INUM(cnt);
  645.   if (cnt < 0) return MAKINUM(SRS(res, -cnt));
  646.   res = MAKINUM(res<<cnt);
  647.   if (INUM(res)>>cnt != INUM(n)) scm_wta(n, (char *)OVFLOW, s_ash);
  648.   return res;
  649. #endif
  650. }
  651.  
  652. PROC (s_bit_extract, "bit-extract", 3, 0, 0, scm_bit_extract);
  653. #ifdef __STDC__
  654. SCM
  655. scm_bit_extract(SCM n, SCM start, SCM end)
  656. #else
  657. SCM
  658. scm_bit_extract(n, start, end)
  659.      SCM n;
  660.      SCM start;
  661.      SCM end;
  662. #endif
  663. {
  664.   ASSERT(INUMP(start), start, ARG2, s_bit_extract);
  665.   ASSERT(INUMP(end), end, ARG3, s_bit_extract);
  666.   start = INUM(start); end = INUM(end);
  667.   ASSERT(end >= start, MAKINUM(end), OUTOFRANGE, s_bit_extract);
  668. #ifdef BIGDIG
  669.   if NINUMP(n)
  670.     return
  671.       scm_logand(scm_difference(scm_integer_expt(MAKINUM(2), MAKINUM(end - start)),
  672.                 MAKINUM(1L)),
  673.          scm_ash(n, MAKINUM(-start)));
  674. #else
  675.   ASSERT(INUMP(n), n, ARG1, s_bit_extract);
  676. #endif
  677.   return MAKINUM((INUM(n)>>start) & ((1L<<(end-start))-1));
  678. }
  679.  
  680. char scm_logtab[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  681. PROC (s_logcount, "logcount", 1, 0, 0, scm_logcount);
  682. #ifdef __STDC__
  683. SCM
  684. scm_logcount (SCM n)
  685. #else
  686. SCM
  687. scm_logcount(n)
  688.      SCM n;
  689. #endif
  690. {
  691.   register unsigned long c = 0;
  692.   register long nn;
  693. #ifdef BIGDIG
  694.   if NINUMP(n) {
  695.     sizet i; BIGDIG *ds, d;
  696.     ASSERT(NIMP(n) && BIGP(n), n, ARG1, s_logcount);
  697.     if BIGSIGN(n) return scm_logcount(scm_difference(MAKINUM(-1L), n));
  698.     ds = BDIGITS(n);
  699.     for(i = NUMDIGS(n); i--; )
  700.       for(d = ds[i]; d; d >>= 4) c += scm_logtab[15 & d];
  701.     return MAKINUM(c);
  702.   }
  703. #else
  704.   ASSERT(INUMP(n), n, ARG1, s_logcount);
  705. #endif
  706.   if ((nn = INUM(n)) < 0) nn = -1 - nn;
  707.   for(; nn; nn >>= 4) c += scm_logtab[15 & nn];
  708.   return MAKINUM(c);
  709. }
  710.  
  711. char scm_ilentab[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
  712. PROC (s_integer_length, "integer-length", 1, 0, 0, scm_integer_length);
  713. #ifdef __STDC__
  714. SCM
  715. scm_integer_length(SCM n)
  716. #else
  717. SCM
  718. scm_integer_length(n)
  719.      SCM n;
  720. #endif
  721. {
  722.   register unsigned long c = 0;
  723.   register long nn;
  724.   unsigned int l = 4;
  725. #ifdef BIGDIG
  726.   if NINUMP(n) {
  727.     BIGDIG *ds, d;
  728.     ASSERT(NIMP(n) && BIGP(n), n, ARG1, s_integer_length);
  729.     if BIGSIGN(n) return scm_integer_length(scm_difference(MAKINUM(-1L), n));
  730.     ds = BDIGITS(n);
  731.     d = ds[c = NUMDIGS(n)-1];
  732.     for(c *= BITSPERDIG; d; d >>= 4) {c += 4; l = scm_ilentab[15 & d];}
  733.     return MAKINUM(c - 4 + l);
  734.   }
  735. #else
  736.   ASSERT(INUMP(n), n, ARG1, s_integer_length);
  737. #endif
  738.   if ((nn = INUM(n)) < 0) nn = -1 - nn;
  739.   for(;nn; nn >>= 4) {c += 4; l = scm_ilentab[15 & nn];}
  740.   return MAKINUM(c - 4 + l);
  741. }
  742.  
  743.  
  744. #ifdef BIGDIG
  745. char s_bignum[] = "bignum";
  746. #ifdef __STDC__
  747. SCM
  748. scm_mkbig(sizet nlen, int sign)
  749. #else
  750. SCM
  751. scm_mkbig(nlen, sign)
  752.      sizet nlen;
  753.      int sign;
  754. #endif
  755. {
  756.   SCM v = nlen;
  757.   if (((v << 16) >> 16) != nlen)
  758.     scm_wta(MAKINUM(nlen), (char *)NALLOC, s_bignum);
  759.   NEWCELL(v);
  760.   DEFER_INTS;
  761.   SETCHARS(v, scm_must_malloc((long)(nlen*sizeof(BIGDIG)), s_bignum));
  762.   SETNUMDIGS(v, nlen, sign?tc16_bigneg:tc16_bigpos);
  763.   ALLOW_INTS;
  764.   return v;
  765. }
  766.  
  767. #ifdef __STDC__
  768. SCM
  769. scm_big2inum(SCM b, sizet l)
  770. #else
  771. SCM
  772. scm_big2inum(b, l)
  773.      SCM b;
  774.      sizet l;
  775. #endif
  776. {
  777.   unsigned long num = 0;
  778.   BIGDIG *tmp = BDIGITS(b);
  779.   while (l--) num = BIGUP(num) + tmp[l];
  780.   if (TYP16(b)==tc16_bigpos) {
  781.     if POSFIXABLE(num) return MAKINUM(num);
  782.   }
  783.   else if UNEGFIXABLE(num) return MAKINUM(-num);
  784.   return b;
  785. }
  786.  
  787.  
  788. char s_adjbig[] = "scm_adjbig";
  789. #ifdef __STDC__
  790. SCM
  791. scm_adjbig(SCM b, sizet nlen)
  792. #else
  793. SCM
  794. scm_adjbig(b, nlen)
  795.      SCM b;
  796.      sizet nlen;
  797. #endif
  798. {
  799.   long nsiz = nlen;
  800.   if (((nsiz << 16) >> 16) != nlen) scm_wta(MAKINUM(nsiz), (char *)NALLOC, s_adjbig);
  801.   DEFER_INTS;
  802.   SETCHARS(b, (BIGDIG *)scm_must_realloc((char *)CHARS(b),
  803.                      (long)(NUMDIGS(b)*sizeof(BIGDIG)),
  804.                      (long)(nsiz*sizeof(BIGDIG)), s_adjbig));
  805.   SETNUMDIGS(b, nsiz, TYP16(b));
  806.   ALLOW_INTS;
  807.   return b;
  808. }
  809.  
  810.  
  811. #ifdef __STDC__
  812. SCM
  813. scm_normbig(SCM b)
  814. #else
  815. SCM
  816. scm_normbig(b)
  817.      SCM b;
  818. #endif
  819. {
  820. #ifndef _UNICOS  
  821.   sizet nlen = NUMDIGS(b);
  822. #else
  823.   int nlen = NUMDIGS(b);    /* unsigned nlen breaks on Cray when nlen => 0 */
  824. #endif
  825.   BIGDIG *zds = BDIGITS(b);
  826.   while (nlen-- && !zds[nlen]); nlen++;
  827.   if (nlen * BITSPERDIG/CHAR_BIT <= sizeof(SCM))
  828.     if INUMP(b = scm_big2inum(b, (sizet)nlen)) return b;
  829.   if (NUMDIGS(b)==nlen) return b;
  830.   return scm_adjbig(b, (sizet)nlen);
  831. }
  832.  
  833.  
  834. #ifdef __STDC__
  835. SCM
  836. scm_copybig(SCM b, int sign)
  837. #else
  838. SCM
  839. scm_copybig(b, sign)
  840.      SCM b;
  841.      int sign;
  842. #endif
  843. {
  844.   sizet i = NUMDIGS(b);
  845.   SCM ans = scm_mkbig(i, sign);
  846.   BIGDIG *src = BDIGITS(b), *dst = BDIGITS(ans);
  847.   while (i--) dst[i] = src[i];
  848.   return ans;
  849. }
  850.  
  851.  
  852. #ifdef __STDC__
  853. SCM
  854. scm_long2big(long n)
  855. #else
  856. SCM
  857. scm_long2big(n)
  858.      long n;
  859. #endif
  860. {
  861.   sizet i = 0;
  862.   BIGDIG *digits;
  863.   SCM ans = scm_mkbig(DIGSPERLONG, n<0);
  864.   digits = BDIGITS(ans);
  865.   if (n < 0) n = -n;
  866.   while (i < DIGSPERLONG) {
  867.     digits[i++] = BIGLO(n);
  868.     n = BIGDN((unsigned long)n);
  869.   }
  870.   return ans;
  871. }
  872.  
  873.  
  874. #ifdef __STDC__
  875. SCM
  876. scm_2ulong2big(unsigned long * np)
  877. #else
  878. SCM
  879. scm_2ulong2big(np)
  880.      unsigned long * np;
  881. #endif
  882. {
  883.   unsigned long n;
  884.   sizet i;
  885.   BIGDIG *digits;
  886.   SCM ans;
  887.  
  888.   ans = scm_mkbig(2 * DIGSPERLONG, 0);
  889.   digits = BDIGITS(ans);
  890.  
  891.   n = np[0];
  892.   for (i = 0; i < DIGSPERLONG; ++i)
  893.     {
  894.       digits[i] = BIGLO(n);
  895.       n = BIGDN((unsigned long)n);
  896.     }
  897.   n = np[1];
  898.   for (i = 0; i < DIGSPERLONG; ++i)
  899.     {
  900.       digits[i + DIGSPERLONG] = BIGLO(n);
  901.       n = BIGDN((unsigned long)n);
  902.     }
  903.   return ans;
  904. }
  905.  
  906.  
  907. #ifdef __STDC__
  908. SCM
  909. scm_ulong2big(unsigned long n)
  910. #else
  911. SCM
  912. scm_ulong2big(n)
  913.      unsigned long n;
  914. #endif
  915. {
  916.   sizet i = 0;
  917.   BIGDIG *digits;
  918.   SCM ans = scm_mkbig(DIGSPERLONG, 0);
  919.   digits = BDIGITS(ans);
  920.   while (i < DIGSPERLONG) {
  921.     digits[i++] = BIGLO(n);
  922.     n = BIGDN(n);
  923.   }
  924.   return ans;
  925. }
  926.  
  927.  
  928. #ifdef __STDC__
  929. int
  930. scm_bigcomp(SCM x, SCM y)
  931. #else
  932. int
  933. scm_bigcomp(x, y)
  934.      SCM x;
  935.      SCM y;
  936. #endif
  937. {
  938.   int xsign = BIGSIGN(x);
  939.   int ysign = BIGSIGN(y);
  940.   sizet xlen, ylen;
  941.   if (ysign < xsign) return 1;
  942.   if (ysign > xsign) return -1;
  943.   if ((ylen = NUMDIGS(y)) > (xlen = NUMDIGS(x))) return (xsign) ? -1 : 1;
  944.   if (ylen < xlen) return (xsign) ? 1 : -1;
  945.   while(xlen-- && (BDIGITS(y)[xlen]==BDIGITS(x)[xlen]));
  946.   if (-1==xlen) return 0;
  947.   return (BDIGITS(y)[xlen] > BDIGITS(x)[xlen]) ?
  948.     (xsign ? -1 : 1) : (xsign ? 1 : -1);
  949. }
  950.  
  951. #ifndef DIGSTOOBIG
  952. long
  953. scm_pseudolong(x)
  954.      long x;
  955. {
  956.   union {
  957.     long l;
  958.     BIGDIG bd[DIGSPERLONG];
  959.   } p;
  960.   sizet i = 0;
  961.   if (x < 0) x = -x;
  962.   while (i < DIGSPERLONG) {p.bd[i++] = BIGLO(x); x = BIGDN(x);}
  963.   /*  p.bd[0] = BIGLO(x); p.bd[1] = BIGDN(x); */
  964.   return p.l;
  965. }
  966.  
  967. #else
  968.  
  969. #ifdef __STDC__
  970. void
  971. scm_longdigs(long x, SCM_BIGDIG digs[])
  972. #else
  973. void
  974. scm_longdigs(x, digs)
  975.      long x;
  976.      SCM_BIGDIG digs[];
  977. #endif
  978. {
  979.   sizet i = 0;
  980.   if (x < 0) x = -x;
  981.   while (i < DIGSPERLONG) {digs[i++] = BIGLO(x); x = BIGDN(x);}
  982. }
  983. #endif
  984.  
  985.  
  986. #ifdef __STDC__
  987. SCM
  988. scm_addbig(SCM_BIGDIG *x, sizet nx, int xsgn, SCM bigy, int sgny)
  989. #else
  990. SCM
  991. scm_addbig(x, nx, xsgn, bigy, sgny)
  992.      SCM_BIGDIG *x;
  993.      sizet nx;
  994.      int xsgn;
  995.      SCM bigy;
  996.      int sgny;
  997. #endif
  998. {
  999.   /* Assumes nx <= NUMDIGS(bigy) */
  1000.   /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
  1001.   long num = 0;
  1002.   sizet i = 0, ny = NUMDIGS(bigy);
  1003.   SCM z = scm_copybig(bigy, BIGSIGN(bigy) ^ sgny);
  1004.   BIGDIG *zds = BDIGITS(z);
  1005.   if (xsgn ^ BIGSIGN(z)) {
  1006.     do {
  1007.       num += (long) zds[i] - x[i];
  1008.       if (num < 0) {zds[i] = num + BIGRAD; num = -1;}
  1009.       else {zds[i] = BIGLO(num); num = 0;}
  1010.     } while (++i < nx);
  1011.     if (num && nx==ny) {
  1012.       num = 1; i = 0;
  1013.       CAR(z) ^= 0x0100;
  1014.       do {
  1015.     num += (BIGRAD-1) - zds[i];
  1016.     zds[i++] = BIGLO(num);
  1017.     num = BIGDN(num);
  1018.       } while (i < ny);
  1019.     }
  1020.     else while (i < ny) {
  1021.       num += zds[i];
  1022.       if (num < 0) {zds[i++] = num + BIGRAD; num = -1;}
  1023.       else {zds[i++] = BIGLO(num); num = 0;}
  1024.     }
  1025.   } else {
  1026.     do {
  1027.       num += (long) zds[i] + x[i];
  1028.       zds[i++] = BIGLO(num);
  1029.       num = BIGDN(num);
  1030.     } while (i < nx);
  1031.     if (!num) return z;
  1032.     while (i < ny) {
  1033.       num += zds[i];
  1034.       zds[i++] = BIGLO(num);
  1035.       num = BIGDN(num);
  1036.       if (!num) return z;
  1037.     }
  1038.     if (num) {z = scm_adjbig(z, ny+1); BDIGITS(z)[ny] = num; return z;}
  1039.   }
  1040.   return scm_normbig(z);
  1041. }
  1042.  
  1043. #ifdef __STDC__
  1044. SCM
  1045. scm_mulbig(SCM_BIGDIG *x, sizet nx, SCM_BIGDIG *y, sizet ny, int sgn)
  1046. #else
  1047. SCM
  1048. scm_mulbig(x, nx, y, ny, sgn)
  1049.      SCM_BIGDIG *x;
  1050.      sizet nx;
  1051.      SCM_BIGDIG *y;
  1052.      sizet ny;
  1053.      int sgn;
  1054. #endif
  1055. {
  1056.   sizet i = 0, j = nx + ny;
  1057.   unsigned long n = 0;
  1058.   SCM z = scm_mkbig(j, sgn);
  1059.   BIGDIG *zds = BDIGITS(z);
  1060.   while (j--) zds[j] = 0;
  1061.   do {
  1062.     j = 0;
  1063.     if (x[i]) {
  1064.       do {
  1065.     n += zds[i + j] + ((unsigned long) x[i] * y[j]);
  1066.     zds[i + j++] = BIGLO(n);
  1067.     n = BIGDN(n);
  1068.       } while (j < ny);
  1069.       if (n) {zds[i + j] = n; n = 0;}
  1070.     }
  1071.   } while (++i < nx);
  1072.   return scm_normbig(z);
  1073. }
  1074.  
  1075. #ifdef __STDC__
  1076. unsigned int
  1077. scm_divbigdig(SCM_BIGDIG *ds, sizet h, SCM_BIGDIG div)
  1078. #else
  1079. unsigned int
  1080. scm_divbigdig(ds, h, div)
  1081.      SCM_BIGDIG *ds;
  1082.      sizet h;
  1083.      SCM_BIGDIG div;
  1084. #endif
  1085. {
  1086.   register unsigned long t2 = 0;
  1087.   while(h--) {
  1088.     t2 = BIGUP(t2) + ds[h];
  1089.     ds[h] = t2 / div;
  1090.     t2 %= div;
  1091.   }
  1092.   return t2;
  1093. }
  1094.  
  1095.  
  1096. #ifdef __STDC__
  1097. SCM
  1098. scm_divbigint(SCM x, long z, int sgn, int mode)
  1099. #else
  1100. SCM
  1101. scm_divbigint(x, z, sgn, mode)
  1102.      SCM x;
  1103.      long z;
  1104.      int sgn;
  1105.      int mode;
  1106. #endif
  1107. {
  1108.   if (z < 0) z = -z;
  1109.   if (z < BIGRAD) {
  1110.     register unsigned long t2 = 0;
  1111.     register BIGDIG *ds = BDIGITS(x);
  1112.     sizet nd = NUMDIGS(x);
  1113.     while(nd--) t2 = (BIGUP(t2) + ds[nd]) % z;
  1114.     if (mode) t2 = z - t2;
  1115.     return MAKINUM(sgn ? -t2 : t2);
  1116.   }
  1117.   {
  1118. #ifndef DIGSTOOBIG
  1119.     unsigned long t2 = scm_pseudolong(z);
  1120.     return scm_divbigbig(BDIGITS(x), NUMDIGS(x), (BIGDIG *)&t2,
  1121.              DIGSPERLONG, sgn, mode); 
  1122. #else
  1123.     BIGDIG t2[DIGSPERLONG];
  1124.     scm_longdigs(z, t2);
  1125.     return scm_divbigbig(BDIGITS(x), NUMDIGS(x), t2, DIGSPERLONG, sgn, mode);
  1126. #endif
  1127.   }
  1128. }
  1129.  
  1130. #ifdef __STDC__
  1131. SCM
  1132. scm_divbigbig(SCM_BIGDIG *x, sizet nx, SCM_BIGDIG *y, sizet ny, int sgn, int modes)
  1133. #else
  1134. SCM
  1135. scm_divbigbig(x, nx, y, ny, sgn, modes)
  1136.      SCM_BIGDIG *x;
  1137.      sizet nx;
  1138.      SCM_BIGDIG *y;
  1139.      sizet ny;
  1140.      int sgn;
  1141.      int modes;
  1142. #endif
  1143. {
  1144.   /* modes description
  1145.      0    remainder
  1146.      1    scm_modulo
  1147.      2    quotient
  1148.      3    quotient but returns 0 if division is not exact. */
  1149.   sizet i = 0, j = 0;
  1150.   long num = 0;
  1151.   unsigned long t2 = 0;
  1152.   SCM z, newy;
  1153.   BIGDIG  d = 0, qhat, *zds, *yds;
  1154.   /* algorithm requires nx >= ny */
  1155.   if (nx < ny)
  1156.     switch (modes) {
  1157.     case 0:            /* remainder -- just return x */
  1158.       z = scm_mkbig(nx, sgn); zds = BDIGITS(z);
  1159.       do {zds[i] = x[i];} while (++i < nx);
  1160.       return z;
  1161.     case 1:            /* scm_modulo -- return y-x */
  1162.       z = scm_mkbig(ny, sgn); zds = BDIGITS(z);
  1163.       do {
  1164.     num += (long) y[i] - x[i];
  1165.     if (num < 0) {zds[i] = num + BIGRAD; num = -1;}
  1166.     else {zds[i] = num; num = 0;}
  1167.       } while (++i < nx);
  1168.       while (i < ny) {
  1169.     num += y[i];
  1170.     if (num < 0) {zds[i++] = num + BIGRAD; num = -1;}
  1171.     else {zds[i++] = num; num = 0;}
  1172.       }
  1173.       goto doadj;
  1174.     case 2: return INUM0;    /* quotient is zero */
  1175.     case 3: return 0;        /* the division is not exact */
  1176.     }
  1177.  
  1178.   z = scm_mkbig(nx==ny ? nx+2 : nx+1, sgn); zds = BDIGITS(z);
  1179.   if (nx==ny) zds[nx+1] = 0;
  1180.   while(!y[ny-1]) ny--;        /* in case y came in as a psuedolong */
  1181.   if (y[ny-1] < (BIGRAD>>1)) {  /* normalize operands */
  1182.     d = BIGRAD/(y[ny-1]+1);
  1183.     newy = scm_mkbig(ny, 0); yds = BDIGITS(newy);
  1184.     while(j < ny)
  1185.       {t2 += (unsigned long) y[j]*d; yds[j++] = BIGLO(t2); t2 = BIGDN(t2);}
  1186.     y = yds; j = 0; t2 = 0;
  1187.     while(j < nx)
  1188.       {t2 += (unsigned long) x[j]*d; zds[j++] = BIGLO(t2); t2 = BIGDN(t2);}
  1189.     zds[j] = t2;
  1190.   }
  1191.   else {zds[j = nx] = 0; while (j--) zds[j] = x[j];}
  1192.   j = nx==ny ? nx+1 : nx;    /* dividend needs more digits than divisor */
  1193.   do {                /* loop over digits of quotient */
  1194.     if (zds[j]==y[ny-1]) qhat = BIGRAD-1;
  1195.     else qhat = (BIGUP(zds[j]) + zds[j-1])/y[ny-1];
  1196.     if (!qhat) continue;
  1197.     i = 0; num = 0; t2 = 0;
  1198.     do {            /* multiply and subtract */
  1199.       t2 += (unsigned long) y[i] * qhat;
  1200.       num += zds[j - ny + i] - BIGLO(t2);
  1201.       if (num < 0) {zds[j - ny + i] = num + BIGRAD; num = -1;}
  1202.       else {zds[j - ny + i] = num; num = 0;}
  1203.       t2 = BIGDN(t2);
  1204.     } while (++i < ny);
  1205.     num += zds[j - ny + i] - t2; /* borrow from high digit; don't update */
  1206.     while (num) {        /* "add back" required */
  1207.       i = 0; num = 0; qhat--;
  1208.       do {
  1209.     num += (long) zds[j - ny + i] + y[i];
  1210.     zds[j - ny + i] = BIGLO(num);
  1211.     num = BIGDN(num);
  1212.       } while (++i < ny);
  1213.       num--;
  1214.     }
  1215.     if (modes & 2) zds[j] = qhat;
  1216.   } while (--j >= ny);
  1217.   switch (modes) {
  1218.   case 3:            /* check that remainder==0 */
  1219.     for(j = ny;j && !zds[j-1];--j) ; if (j) return 0;
  1220.   case 2:            /* move quotient down in z */
  1221.     j = (nx==ny ? nx+2 : nx+1) - ny;
  1222.     for (i = 0;i < j;i++) zds[i] = zds[i+ny];
  1223.     ny = i;
  1224.     break;
  1225.   case 1:            /* subtract for scm_modulo */
  1226.     i = 0; num = 0; j = 0;
  1227.     do {num += y[i] - zds[i];
  1228.     j = j | zds[i];
  1229.     if (num < 0) {zds[i] = num + BIGRAD; num = -1;}
  1230.     else {zds[i] = num; num = 0;}
  1231.       } while (++i < ny);
  1232.     if (!j) return INUM0;
  1233.   case 0:            /* just normalize remainder */
  1234.     if (d) scm_divbigdig(zds, ny, d);
  1235.   }
  1236.  doadj:
  1237.   for(j = ny;j && !zds[j-1];--j) ;
  1238.   if (j * BITSPERDIG <= sizeof(SCM)*CHAR_BIT)
  1239.     if INUMP(z = scm_big2inum(z, j)) return z;
  1240.   return scm_adjbig(z, j);
  1241. }
  1242. #endif
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248. /*** NUMBERS -> STRINGS ***/
  1249. #ifdef FLOATS
  1250. int scm_dblprec;
  1251. static double fx[] = {0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
  1252.             5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
  1253.             5e-11,5e-12,5e-13,5e-14,5e-15,
  1254.             5e-16,5e-17,5e-18,5e-19,5e-20};
  1255.  
  1256.  
  1257.  
  1258. #ifdef __STDC__
  1259. static sizet
  1260. idbl2str(double f, char *a)
  1261. #else
  1262. static sizet
  1263. idbl2str(f, a)
  1264.      double f;
  1265.      char *a;
  1266. #endif
  1267. {
  1268.   int efmt, dpt, d, i, wp = scm_dblprec;
  1269.   sizet ch = 0;
  1270.   int exp = 0;
  1271.  
  1272.   if (f == 0.0) goto zero;    /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;}*/
  1273.   if (f < 0.0) {f = -f;a[ch++]='-';}
  1274.   else if (f > 0.0) ;
  1275.   else goto funny;
  1276.   if (IS_INF(f))
  1277.     {
  1278.       if (ch == 0) a[ch++]='+';
  1279.     funny: a[ch++]='#'; a[ch++]='.'; a[ch++]='#'; return ch;
  1280.     }
  1281. # ifdef DBL_MIN_10_EXP        /* Prevent unnormalized values, as from 
  1282.                    make-uniform-vector, from causing infinite loops. */
  1283.   while (f < 1.0) {f *= 10.0;  if (exp-- < DBL_MIN_10_EXP) goto funny;}
  1284.   while (f > 10.0) {f *= 0.10; if (exp++ > DBL_MAX_10_EXP) goto funny;}
  1285. # else
  1286.   while (f < 1.0) {f *= 10.0; exp--;}
  1287.   while (f > 10.0) {f /= 10.0; exp++;}
  1288. # endif
  1289.   if (f+fx[wp] >= 10.0) {f = 1.0; exp++;}
  1290.  zero:
  1291. # ifdef ENGNOT
  1292.   dpt = (exp+9999)%3;
  1293.   exp -= dpt++;
  1294.   efmt = 1;
  1295. # else
  1296.   efmt = (exp < -3) || (exp > wp+2);
  1297.   if (!efmt)
  1298.     if (exp < 0) {
  1299.       a[ch++] = '0';
  1300.       a[ch++] = '.';
  1301.       dpt = exp;
  1302.       while (++dpt)  a[ch++] = '0';
  1303.     } else
  1304.       dpt = exp+1;
  1305.   else
  1306.     dpt = 1;
  1307. # endif
  1308.  
  1309.   do {
  1310.     d = f;
  1311.     f -= d;
  1312.     a[ch++] = d+'0';
  1313.     if (f < fx[wp])  break;
  1314.     if (f+fx[wp] >= 1.0) {
  1315.       a[ch-1]++;
  1316.       break;
  1317.     }
  1318.     f *= 10.0;
  1319.     if (!(--dpt))  a[ch++] = '.';
  1320.   } while (wp--);
  1321.  
  1322.   if (dpt > 0)
  1323. # ifndef ENGNOT
  1324.     if ((dpt > 4) && (exp > 6)) {
  1325.       d = (a[0]=='-'?2:1);
  1326.       for (i = ch++; i > d; i--)
  1327.     a[i] = a[i-1];
  1328.       a[d] = '.';
  1329.       efmt = 1;
  1330.     } else
  1331. # endif
  1332.       {
  1333.     while (--dpt)  a[ch++] = '0';
  1334.     a[ch++] = '.';
  1335.       }
  1336.   if (a[ch-1]=='.')  a[ch++]='0'; /* trailing zero */
  1337.   if (efmt && exp) {
  1338.     a[ch++] = 'e';
  1339.     if (exp < 0) {
  1340.       exp = -exp;
  1341.       a[ch++] = '-';
  1342.     }
  1343.     for (i = 10; i <= exp; i *= 10);
  1344.     for (i /= 10; i; i /= 10) {
  1345.       a[ch++] = exp/i + '0';
  1346.       exp %= i;
  1347.     }
  1348.   }
  1349.   return ch;
  1350. }
  1351.  
  1352. #ifdef __STDC__
  1353. static sizet
  1354. iflo2str(SCM flt, char *str)
  1355. #else
  1356. static sizet
  1357. iflo2str(flt, str)
  1358.      SCM flt;
  1359.      char *str;
  1360. #endif
  1361. {
  1362.   sizet i;
  1363. # ifdef SINGLES
  1364.   if SINGP(flt) i = idbl2str(FLO(flt), str);
  1365.   else
  1366. # endif
  1367.     i = idbl2str(REAL(flt), str);
  1368.   if CPLXP(flt) {
  1369.     if(0 <= IMAG(flt))        /* jeh */
  1370.       str[i++] = '+';        /* jeh */
  1371.     i += idbl2str(IMAG(flt), &str[i]);
  1372.     str[i++] = 'i';
  1373.   }
  1374.   return i;
  1375. }
  1376. #endif                /* FLOATS */
  1377.  
  1378. #ifdef __STDC__
  1379. sizet
  1380. scm_iint2str(long num, int rad, char *p)
  1381. #else
  1382. sizet
  1383. scm_iint2str(num, rad, p)
  1384.      long num;
  1385.      int rad;
  1386.      char *p;
  1387. #endif
  1388. {
  1389.   sizet j;
  1390.   register int i = 1, d;
  1391.   register long n = num;
  1392.   if (n < 0) {n = -n; i++;}
  1393.   for (n /= rad;n > 0;n /= rad) i++;
  1394.   j = i;
  1395.   n = num;
  1396.   if (n < 0) {n = -n; *p++ = '-'; i--;}
  1397.   while (i--) {
  1398.     d = n % rad;
  1399.     n /= rad;
  1400.     p[i] = d + ((d < 10) ? '0' : 'a' - 10);
  1401.   }
  1402.   return j;
  1403. }
  1404.  
  1405.  
  1406. #ifdef BIGDIG
  1407. #ifdef __STDC__
  1408. static SCM
  1409. big2str(SCM b, register unsigned int radix)
  1410. #else
  1411. static SCM
  1412. big2str(b, radix)
  1413.      SCM b;
  1414.      register unsigned int radix;
  1415. #endif
  1416. {
  1417.   SCM t = scm_copybig(b, 0);    /* sign of temp doesn't matter */
  1418.   register BIGDIG *ds = BDIGITS(t);
  1419.   sizet i = NUMDIGS(t);
  1420.   sizet j = radix==16 ? (BITSPERDIG*i)/4+2
  1421.     : radix >= 10 ? (BITSPERDIG*i*241L)/800+2
  1422.       : (BITSPERDIG*i)+2;
  1423.   sizet k = 0;
  1424.   sizet radct = 0;
  1425.   sizet ch;            /* jeh */
  1426.   BIGDIG radpow = 1, radmod = 0;
  1427.   SCM ss = scm_makstr((long)j, 0);
  1428.   char *s = CHARS(ss), c;
  1429.   while ((long) radpow * radix < BIGRAD) {
  1430.     radpow *= radix;
  1431.     radct++;
  1432.   }
  1433.   s[0] = tc16_bigneg==TYP16(b) ? '-' : '+';
  1434.   while ((i || radmod) && j) {
  1435.     if (k == 0) {
  1436.       radmod = (BIGDIG)scm_divbigdig(ds, i, radpow);
  1437.       k = radct;
  1438.       if (!ds[i-1]) i--;
  1439.     }
  1440.     c = radmod % radix; radmod /= radix; k--;
  1441.     s[--j] = c < 10 ? c + '0' : c + 'a' - 10;
  1442.   }
  1443.   ch = s[0] == '-' ? 1 : 0;    /* jeh */
  1444.   if (ch < j) {            /* jeh */
  1445.     for(i = j;j < LENGTH(ss);j++) s[ch+j-i] = s[j]; /* jeh */
  1446.     scm_resizuve(ss, (SCM)MAKINUM(ch+LENGTH(ss)-i)); /* jeh */
  1447.   }
  1448.   return ss;
  1449. }
  1450. #endif
  1451.  
  1452.  
  1453. PROC (s_number_to_string, "number->string", 1, 1, 0, scm_number_to_string);
  1454. #ifdef __STDC__
  1455. SCM
  1456. scm_number_to_string(SCM x, SCM radix)
  1457. #else
  1458. SCM
  1459. scm_number_to_string(x, radix)
  1460.      SCM x;
  1461.      SCM radix;
  1462. #endif
  1463. {
  1464.   if UNBNDP(radix) radix=MAKINUM(10L);
  1465.   else ASSERT(INUMP(radix), radix, ARG2, s_number_to_string);
  1466. #ifdef FLOATS
  1467.   if NINUMP(x) {
  1468.     char num_buf[FLOBUFLEN];
  1469. # ifdef BIGDIG
  1470.     ASRTGO(NIMP(x), badx);
  1471.     if BIGP(x) return big2str(x, (unsigned int)INUM(radix));
  1472. #  ifndef RECKLESS
  1473.     if (!(INEXP(x)))
  1474.     badx: scm_wta(x, (char *)ARG1, s_number_to_string);
  1475. #  endif
  1476. # else
  1477.     ASSERT(NIMP(x) && INEXP(x), x, ARG1, s_number_to_string);
  1478. # endif
  1479.     return scm_makfromstr(num_buf, iflo2str(x, num_buf), 0);
  1480.   }
  1481. #else
  1482. # ifdef BIGDIG
  1483.   if NINUMP(x) {
  1484.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_number_to_string);
  1485.     return big2str(x, (unsigned int)INUM(radix));
  1486.   }
  1487. # else
  1488.   ASSERT(INUMP(x), x, ARG1, s_number_to_string);
  1489. # endif
  1490. #endif
  1491.   {
  1492.     char num_buf[INTBUFLEN];
  1493.     return scm_makfromstr(num_buf,
  1494.               scm_iint2str(INUM(x), (int)INUM(radix), num_buf), 0);
  1495.   }
  1496. }
  1497.  
  1498.  
  1499. /* These print routines are stubbed here so that scm_repl.c doesn't need
  1500.    FLOATS or BIGDIGs conditionals */
  1501. #ifdef __STDC__
  1502. int
  1503. scm_floprint(SCM sexp, SCM port, int writing)
  1504. #else
  1505. int
  1506. scm_floprint(sexp, port, writing)
  1507.      SCM sexp;
  1508.      SCM port;
  1509.      int writing;
  1510. #endif
  1511. {
  1512. #ifdef FLOATS
  1513.   char num_buf[FLOBUFLEN];
  1514.   scm_lfwrite(num_buf, (sizet)sizeof(char), iflo2str(sexp, num_buf), port);
  1515. #else
  1516.   scm_ipruk("float", sexp, port);
  1517. #endif
  1518.   return !0;
  1519. }
  1520.  
  1521.  
  1522. #ifdef __STDC__
  1523. int
  1524. scm_bigprint(SCM exp, SCM port, int writing)
  1525. #else
  1526. int
  1527. scm_bigprint(exp, port, writing)
  1528.      SCM exp;
  1529.      SCM port;
  1530.      int writing;
  1531. #endif
  1532. {
  1533. #ifdef BIGDIG
  1534.   exp = big2str(exp, (unsigned int)10);
  1535.   scm_lfwrite(CHARS(exp), (sizet)sizeof(char), (sizet)LENGTH(exp), port);
  1536. #else
  1537.   scm_ipruk("bignum", exp, port);
  1538. #endif
  1539.   return !0;
  1540. }
  1541. /*** END nums->strs ***/
  1542.  
  1543. /*** STRINGS -> NUMBERS ***/
  1544. #ifdef BIGDIG
  1545. #ifdef __STDC__
  1546. SCM
  1547. scm_istr2int(char *str, long len, long radix)
  1548. #else
  1549. SCM
  1550. scm_istr2int(str, len, radix)
  1551.      char *str;
  1552.      long len;
  1553.      long radix;
  1554. #endif
  1555. {
  1556.   sizet j;
  1557.   register sizet k, blen = 1;
  1558.   sizet i = 0;
  1559.   int c;
  1560.   SCM res;
  1561.   register BIGDIG *ds;
  1562.   register unsigned long t2;
  1563.  
  1564.   if (0 >= len) return BOOL_F;    /* zero scm_length */
  1565.   if (16==radix) j = 1+(4*len*sizeof(char))/(BITSPERDIG);
  1566.   else if (10 <= radix)
  1567.     j = 1+(84*len*sizeof(char))/(BITSPERDIG*25);
  1568.   else j = 1+(len*sizeof(char))/(BITSPERDIG);
  1569.   switch (str[0]) {        /* leading sign */
  1570.   case '-':
  1571.   case '+': if (++i==len) return BOOL_F; /* bad if lone `+' or `-' */
  1572.   }
  1573.   res = scm_mkbig(j, '-'==str[0]);
  1574.   ds = BDIGITS(res);
  1575.   for (k = j;k--;) ds[k] = 0;
  1576.   do {
  1577.     switch (c = str[i++]) {
  1578.     case DIGITS:
  1579.       c = c - '0';
  1580.       goto accumulate;
  1581.     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  1582.       c = c-'A'+10;
  1583.       goto accumulate;
  1584.     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  1585.       c = c-'a'+10;
  1586.     accumulate:
  1587.       if (c >= radix) return BOOL_F; /* bad digit for radix */
  1588.       k = 0;
  1589.       t2 = c;
  1590.     moretodo:
  1591.       while(k < blen) {
  1592.     /*    printf("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]);*/
  1593.     t2 += ds[k]*radix;
  1594.     ds[k++] = BIGLO(t2);
  1595.     t2 = BIGDN(t2);
  1596.       }
  1597.       ASSERT(blen <= j, (SCM)MAKINUM(blen), OVFLOW, "bignum");
  1598.       if (t2) {blen++; goto moretodo;}
  1599.       break;
  1600.     default:
  1601.       return BOOL_F;        /* not a digit */
  1602.     }
  1603.   } while (i < len);
  1604.   if (blen * BITSPERDIG/CHAR_BIT <= sizeof(SCM))
  1605.     if INUMP(res = scm_big2inum(res, blen)) return res;
  1606.   if (j==blen) return res;
  1607.   return scm_adjbig(res, blen);
  1608. }
  1609. #else
  1610.  
  1611.  
  1612.  
  1613. #ifdef __STDC__
  1614. SCM
  1615. scm_istr2int(char *str, long len, long radix)
  1616. #else
  1617. SCM
  1618. scm_istr2int(str, len, radix)
  1619.      char *str;
  1620.      long len;
  1621.      long radix;
  1622. #endif
  1623. {
  1624.   register long n = 0, ln;
  1625.   register int c;
  1626.   register int i = 0;
  1627.   int lead_neg = 0;
  1628.   if (0 >= len) return BOOL_F;    /* zero scm_length */
  1629.   switch (*str) {        /* leading sign */
  1630.   case '-': lead_neg = 1;
  1631.   case '+': if (++i==len) return BOOL_F; /* bad if lone `+' or `-' */
  1632.   }
  1633.  
  1634.   do {
  1635.     switch (c = str[i++]) {
  1636.     case DIGITS:
  1637.       c = c - '0';
  1638.       goto accumulate;
  1639.     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  1640.       c = c-'A'+10;
  1641.       goto accumulate;
  1642.     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  1643.       c = c-'a'+10;
  1644.     accumulate:
  1645.       if (c >= radix) return BOOL_F; /* bad digit for radix */
  1646.       ln = n;
  1647.       n = n * radix - c;
  1648.       /* Negation is a workaround for HP700 cc bug */
  1649.       if (n > ln || (-n > -MOST_NEGATIVE_FIXNUM)) goto ovfl;
  1650.       break;
  1651.     default:
  1652.       return BOOL_F;        /* not a digit */
  1653.     }
  1654.   } while (i < len);
  1655.   if (!lead_neg) if ((n = -n) > MOST_POSITIVE_FIXNUM) goto ovfl;
  1656.   return MAKINUM(n);
  1657.  ovfl:                /* overflow scheme integer */
  1658.   return BOOL_F;
  1659. }
  1660. #endif
  1661.  
  1662. #ifdef FLOATS
  1663. #ifdef __STDC__
  1664. SCM
  1665. scm_istr2flo(char *str, long len, long radix)
  1666. #else
  1667. SCM
  1668. scm_istr2flo(str, len, radix)
  1669.      char *str;
  1670.      long len;
  1671.      long radix;
  1672. #endif
  1673. {
  1674.   register int c, i = 0;
  1675.   double lead_sgn;
  1676.   double res = 0.0, tmp = 0.0;
  1677.   int flg = 0;
  1678.   int point = 0;
  1679.   SCM second;
  1680.  
  1681.   if (i >= len) return BOOL_F;    /* zero scm_length */
  1682.  
  1683.   switch (*str) {        /* leading sign */
  1684.   case '-': lead_sgn = -1.0; i++; break;
  1685.   case '+': lead_sgn = 1.0; i++; break;
  1686.   default : lead_sgn = 0.0;
  1687.   }
  1688.   if (i==len) return BOOL_F;    /* bad if lone `+' or `-' */
  1689.  
  1690.   if (str[i]=='i' || str[i]=='I') { /* handle `+i' and `-i'   */
  1691.     if (lead_sgn==0.0) return BOOL_F; /* must have leading sign */
  1692.     if (++i < len) return BOOL_F; /* `i' not last character */
  1693.     return scm_makdbl(0.0, lead_sgn);
  1694.   }
  1695.   do {                /* check initial digits */
  1696.     switch (c = str[i]) {
  1697.     case DIGITS:
  1698.       c = c - '0';
  1699.       goto accum1;
  1700.     case 'D': case 'E': case 'F':
  1701.       if (radix==10) goto out1; /* must be exponent */
  1702.     case 'A': case 'B': case 'C':
  1703.       c = c-'A'+10;
  1704.       goto accum1;
  1705.     case 'd': case 'e': case 'f':
  1706.       if (radix==10) goto out1;
  1707.     case 'a': case 'b': case 'c':
  1708.       c = c-'a'+10;
  1709.     accum1:
  1710.       if (c >= radix) return BOOL_F; /* bad digit for radix */
  1711.       res = res * radix + c;
  1712.       flg = 1;            /* res is valid */
  1713.       break;
  1714.     default:
  1715.       goto out1;
  1716.     }
  1717.   } while (++i < len);
  1718.  out1:
  1719.  
  1720.   /* if true, then we did see a digit above, and res is valid */
  1721.   if (i==len) goto done;
  1722.  
  1723.   /* By here, must have seen a digit,
  1724.      or must have next char be a `.' with radix==10 */
  1725.   if (!flg)
  1726.     if (!(str[i]=='.' && radix==10))
  1727.       return BOOL_F;
  1728.  
  1729.   while (str[i]=='#') {        /* optional sharps */
  1730.     res *= radix;
  1731.     if (++i==len) goto done;
  1732.   }
  1733.  
  1734.   if (str[i]=='/') {
  1735.     while (++i < len) {
  1736.       switch (c = str[i]) {
  1737.       case DIGITS:
  1738.     c = c - '0';
  1739.     goto accum2;
  1740.       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  1741.     c = c-'A'+10;
  1742.     goto accum2;
  1743.       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  1744.     c = c-'a'+10;
  1745.       accum2:
  1746.     if (c >= radix) return BOOL_F;
  1747.     tmp = tmp * radix + c;
  1748.     break;
  1749.       default:
  1750.     goto out2;
  1751.       }
  1752.     }
  1753.   out2:
  1754.     if (tmp==0.0) return BOOL_F; /* `slash zero' not allowed */
  1755.     if (i < len)
  1756.       while (str[i]=='#') {    /* optional sharps */
  1757.     tmp *= radix;
  1758.     if (++i==len) break;
  1759.       }
  1760.     res /= tmp;
  1761.     goto done;
  1762.   }
  1763.  
  1764.   if (str[i]=='.') {        /* decimal point notation */
  1765.     if (radix != 10) return BOOL_F; /* must be radix 10 */
  1766.     while (++i < len) {
  1767.       switch (c = str[i]) {
  1768.       case DIGITS:
  1769.     point--;
  1770.     res = res*10.0 + c-'0';
  1771.     flg = 1;
  1772.     break;
  1773.       default:
  1774.     goto out3;
  1775.       }
  1776.     }
  1777.   out3:
  1778.     if (!flg) return BOOL_F;    /* no digits before or after decimal point */
  1779.     if (i==len) goto adjust;
  1780.     while (str[i]=='#') {    /* ignore remaining sharps */
  1781.       if (++i==len) goto adjust;
  1782.     }
  1783.   }
  1784.  
  1785.   switch (str[i]) {        /* exponent */
  1786.   case 'd': case 'D':
  1787.   case 'e': case 'E':
  1788.   case 'f': case 'F':
  1789.   case 'l': case 'L':
  1790.   case 's': case 'S': {
  1791.     int expsgn = 1, expon = 0;
  1792.     if (radix != 10) return BOOL_F; /* only in radix 10 */
  1793.     if (++i==len) return BOOL_F; /* bad exponent */
  1794.     switch (str[i]) {
  1795.     case '-':  expsgn=(-1);
  1796.     case '+':  if (++i==len) return BOOL_F; /* bad exponent */
  1797.     }
  1798.     if (str[i] < '0' || str[i] > '9') return BOOL_F; /* bad exponent */
  1799.     do {
  1800.       switch (c = str[i]) {
  1801.       case DIGITS:
  1802.     expon = expon*10 + c-'0';
  1803.     if (expon > MAXEXP)  return BOOL_F; /* exponent too large */
  1804.     break;
  1805.       default:
  1806.     goto out4;
  1807.       }
  1808.     } while (++i < len);
  1809.   out4:
  1810.     point += expsgn*expon;
  1811.   }
  1812.   }
  1813.  
  1814.  adjust:
  1815.   if (point >= 0)
  1816.     while (point--)  res *= 10.0;
  1817.   else
  1818. # ifdef _UNICOS
  1819.     while (point++)  res *= 0.1; 
  1820. # else
  1821.   while (point++)  res /= 10.0;
  1822. # endif
  1823.  
  1824.  done:
  1825.   /* at this point, we have a legitimate floating point result */
  1826.   if (lead_sgn==-1.0)  res = -res;
  1827.   if (i==len) return scm_makdbl(res, 0.0);
  1828.  
  1829.   if (str[i]=='i' || str[i]=='I') { /* pure imaginary number  */
  1830.     if (lead_sgn==0.0) return BOOL_F; /* must have leading sign */
  1831.     if (++i < len) return BOOL_F; /* `i' not last character */
  1832.     return scm_makdbl(0.0, res);
  1833.   }
  1834.  
  1835.   switch (str[i++]) {
  1836.   case '-':  lead_sgn = -1.0; break;
  1837.   case '+':  lead_sgn = 1.0;  break;
  1838.   case '@': {            /* polar input for complex number */
  1839.     /* get a `real' for scm_angle */
  1840.     second = scm_istr2flo(&str[i], (long)(len-i), radix);
  1841.     if (!(INEXP(second))) return BOOL_F; /* not `real' */
  1842.     if (CPLXP(second))    return BOOL_F; /* not `real' */
  1843.     tmp = REALPART(second);
  1844.     return scm_makdbl(res*cos(tmp), res*sin(tmp));
  1845.   }
  1846.   default: return BOOL_F;
  1847.   }
  1848.  
  1849.   /* at this point, last char must be `i' */
  1850.   if (str[len-1] != 'i' && str[len-1] != 'I') return BOOL_F;
  1851.   /* handles `x+i' and `x-i' */
  1852.   if (i==(len-1))  return scm_makdbl(res, lead_sgn);
  1853.   /* get a `ureal' for complex part */
  1854.   second = scm_istr2flo(&str[i], (long)((len-i)-1), radix);
  1855.   if (!(INEXP(second))) return BOOL_F; /* not `ureal' */
  1856.   if (CPLXP(second))    return BOOL_F; /* not `ureal' */
  1857.   tmp = REALPART(second);
  1858.   if (tmp < 0.0)    return BOOL_F; /* not `ureal' */
  1859.   return scm_makdbl(res, (lead_sgn*tmp));
  1860. }
  1861. #endif                /* FLOATS */
  1862.  
  1863.  
  1864. #ifdef __STDC__
  1865. SCM
  1866. scm_istring2number(char *str, long len, long radix)
  1867. #else
  1868. SCM
  1869. scm_istring2number(str, len, radix)
  1870.      char *str;
  1871.      long len;
  1872.      long radix;
  1873. #endif
  1874. {
  1875.   int i = 0;
  1876.   char ex = 0;
  1877.   char ex_p = 0, rx_p = 0;    /* Only allow 1 exactness and 1 radix prefix */
  1878.   SCM res;
  1879.   if (len==1)
  1880.     if (*str=='+' || *str=='-') /* Catches lone `+' and `-' for speed */
  1881.       return BOOL_F;
  1882.  
  1883.   while ((len-i) >= 2  &&  str[i]=='#' && ++i)
  1884.     switch (str[i++]) {
  1885.     case 'b': case 'B':  if (rx_p++) return BOOL_F; radix = 2;  break;
  1886.     case 'o': case 'O':  if (rx_p++) return BOOL_F; radix = 8;  break;
  1887.     case 'd': case 'D':  if (rx_p++) return BOOL_F; radix = 10; break;
  1888.     case 'x': case 'X':  if (rx_p++) return BOOL_F; radix = 16; break;
  1889.     case 'i': case 'I':  if (ex_p++) return BOOL_F; ex = 2;     break;
  1890.     case 'e': case 'E':  if (ex_p++) return BOOL_F; ex = 1;     break;
  1891.     default:  return BOOL_F;
  1892.     }
  1893.  
  1894.   switch (ex) {
  1895.   case 1:
  1896.     return scm_istr2int(&str[i], len-i, radix);
  1897.   case 0:
  1898.     res = scm_istr2int(&str[i], len-i, radix);
  1899.     if NFALSEP(res) return res;
  1900. #ifdef FLOATS
  1901.   case 2: return scm_istr2flo(&str[i], len-i, radix);
  1902. #endif
  1903.   }
  1904.   return BOOL_F;
  1905. }
  1906.  
  1907.  
  1908. PROC (s_string_to_number, "string->number", 1, 1, 0, scm_string_to_number);
  1909. #ifdef __STDC__
  1910. SCM
  1911. scm_string_to_number(SCM str, SCM radix)
  1912. #else
  1913. SCM
  1914. scm_string_to_number(str, radix)
  1915.      SCM str;
  1916.      SCM radix;
  1917. #endif
  1918. {
  1919.   if UNBNDP(radix) radix=MAKINUM(10L);
  1920.   else ASSERT(INUMP(radix), radix, ARG2, s_string_to_number);
  1921.   ASSERT(NIMP(str) && STRINGP(str), str, ARG1, s_string_to_number);
  1922.   return scm_istring2number(CHARS(str), LENGTH(str), INUM(radix));
  1923. }
  1924. /*** END strs->nums ***/
  1925.  
  1926. #ifdef FLOATS
  1927. #ifdef __STDC__
  1928. SCM
  1929. scm_makdbl (double x, double y)
  1930. #else
  1931. SCM
  1932. scm_makdbl (x, y)
  1933.      double x;
  1934.      double y;
  1935. #endif
  1936. {
  1937.   SCM z;
  1938.   if ((y==0.0) && (x==0.0)) return flo0;
  1939.   NEWCELL(z);
  1940.   DEFER_INTS;
  1941.   if (y==0.0) {
  1942. # ifdef SINGLES
  1943.     float fx = x;
  1944. #  ifndef SINGLESONLY
  1945.     if ((-FLTMAX < x) && (x < FLTMAX) && (fx==x))
  1946. #  endif
  1947.       {
  1948.     CAR(z) = tc_flo;
  1949.     FLO(z) = x;
  1950.     ALLOW_INTS;
  1951.     return z;
  1952.       }
  1953. # endif/* def SINGLES */
  1954.     CDR(z) = (SCM)scm_must_malloc(1L*sizeof(double), "real");
  1955.     CAR(z) = tc_dblr;
  1956.   }
  1957.   else {
  1958.     CDR(z) = (SCM)scm_must_malloc(2L*sizeof(double), "complex");
  1959.     CAR(z) = tc_dblc;
  1960.     IMAG(z) = y;
  1961.   }
  1962.   REAL(z) = x;
  1963.   ALLOW_INTS;
  1964.   return z;
  1965. }
  1966. #endif
  1967.  
  1968.  
  1969. #ifdef __STDC__
  1970. SCM
  1971. scm_bigequal(SCM x, SCM y)
  1972. #else
  1973. SCM
  1974. scm_bigequal(x, y)
  1975.      SCM x;
  1976.      SCM y;
  1977. #endif
  1978. {
  1979. #ifdef BIGDIG
  1980.   if (0==scm_bigcomp(x, y)) return BOOL_T;
  1981. #endif
  1982.   return BOOL_F;
  1983. }
  1984.  
  1985.  
  1986. #ifdef __STDC__
  1987. SCM
  1988. scm_floequal(SCM x, SCM y)
  1989. #else
  1990. SCM
  1991. scm_floequal(x, y)
  1992.      SCM x;
  1993.      SCM y;
  1994. #endif
  1995. {
  1996. #ifdef FLOATS
  1997.   if (REALPART(x) != REALPART(y)) return BOOL_F;
  1998.   if (!(CPLXP(x) && (IMAG(x) != IMAG(y)))) return BOOL_T;
  1999. #endif
  2000.   return BOOL_F;
  2001. }
  2002.  
  2003.  
  2004.  
  2005.  
  2006. PROC (s_number_p, "number?", 1, 0, 0, scm_number_p);
  2007. PROC (s_complex_p, "complex?", 1, 0, 0, scm_number_p);
  2008. #ifdef __STDC__
  2009. SCM
  2010. scm_number_p(SCM x)
  2011. #else
  2012. SCM
  2013. scm_number_p(x)
  2014.      SCM x;
  2015. #endif
  2016. {
  2017.   if INUMP(x) return BOOL_T;
  2018. #ifdef FLOATS
  2019.   if (NIMP(x) && NUMP(x)) return BOOL_T;
  2020. #else
  2021. # ifdef BIGDIG
  2022.   if (NIMP(x) && NUMP(x)) return BOOL_T;
  2023. # endif
  2024. #endif
  2025.   return BOOL_F;
  2026. }
  2027.  
  2028.  
  2029.  
  2030. #ifdef FLOATS
  2031. PROC (s_real_p, "real?", 1, 0, 0, scm_real_p);
  2032. PROC (s_rational_p, "rational?", 1, 0, 0, scm_real_p);
  2033. #ifdef __STDC__
  2034. SCM
  2035. scm_real_p(SCM x)
  2036. #else
  2037. SCM
  2038. scm_real_p(x)
  2039.      SCM x;
  2040. #endif
  2041. {
  2042.   if (INUMP(x))
  2043.     return BOOL_T;
  2044.   if (IMP(x))
  2045.     return BOOL_F;
  2046.   if (REALP(x))
  2047.     return BOOL_T;
  2048. # ifdef BIGDIG
  2049.   if (BIGP(x))
  2050.     return BOOL_T;
  2051. # endif
  2052.   return BOOL_F;
  2053. }
  2054.  
  2055.  
  2056.  
  2057. PROC (s_int_p, "int?", 1, 0, 0, scm_int_p);
  2058. #ifdef __STDC__
  2059. SCM
  2060. scm_int_p(SCM x)
  2061. #else
  2062. SCM
  2063. scm_int_p(x)
  2064.      SCM x;
  2065. #endif
  2066. {
  2067.   double r;
  2068.   if INUMP(x) return BOOL_T;
  2069.   if IMP(x) return BOOL_F;
  2070. # ifdef BIGDIG
  2071.   if BIGP(x) return BOOL_T;
  2072. # endif
  2073.   if (!INEXP(x)) return BOOL_F;
  2074.   if CPLXP(x) return BOOL_F;
  2075.   r = REALPART(x);
  2076.   if (r==floor(r)) return BOOL_T;
  2077.   return BOOL_F;
  2078. }
  2079.  
  2080.  
  2081.  
  2082. #endif                /* FLOATS */
  2083.  
  2084. PROC (s_inexact_p, "inexact?", 1, 0, 0, scm_inexact_p);
  2085. #ifdef __STDC__
  2086. SCM
  2087. scm_inexact_p(SCM x)
  2088. #else
  2089. SCM
  2090. scm_inexact_p(x)
  2091.      SCM x;
  2092. #endif
  2093. {
  2094. #ifdef FLOATS
  2095.   if (NIMP(x) && INEXP(x)) return BOOL_T;
  2096. #endif
  2097.   return BOOL_F;
  2098. }
  2099.  
  2100.  
  2101.  
  2102.  
  2103. PROC1 (s_eq_p, "=?", tc7_rpsubr, scm_num_eq_p);
  2104. #ifdef __STDC__
  2105. SCM
  2106. scm_num_eq_p(SCM x, SCM y)
  2107. #else
  2108. SCM
  2109. scm_equal_p(x, y)
  2110.      SCM x;
  2111.      SCM y;
  2112. #endif
  2113. {
  2114. #ifdef FLOATS
  2115.   SCM t;
  2116.   if NINUMP(x) {
  2117. # ifdef BIGDIG
  2118. #  ifndef RECKLESS
  2119.     if (!(NIMP(x)))
  2120.     badx: scm_wta(x, (char *)ARG1, s_eq_p);
  2121. #  endif
  2122.     if BIGP(x) {
  2123.       if INUMP(y) return BOOL_F;
  2124.       ASRTGO(NIMP(y), bady);
  2125.       if BIGP(y) return (0==scm_bigcomp(x, y)) ? BOOL_T : BOOL_F;
  2126.       ASRTGO(INEXP(y), bady);
  2127.     bigreal:
  2128.       return (REALP(y) && (scm_big2dbl(x)==REALPART(y))) ? BOOL_T : BOOL_F;
  2129.     }
  2130.     ASRTGO(INEXP(x), badx);
  2131. # else
  2132.     ASSERT(NIMP(x) && INEXP(x), x, ARG1, s_eq_p);
  2133. # endif
  2134.     if INUMP(y) {t = x; x = y; y = t; goto realint;}
  2135. # ifdef BIGDIG
  2136.     ASRTGO(NIMP(y), bady);
  2137.     if BIGP(y) {t = x; x = y; y = t; goto bigreal;}
  2138.     ASRTGO(INEXP(y), bady);
  2139. # else
  2140.     ASRTGO(NIMP(y) && INEXP(y), bady);
  2141. # endif
  2142.     if (REALPART(x) != REALPART(y)) return BOOL_F;
  2143.     if CPLXP(x)
  2144.       return (CPLXP(y) && (IMAG(x)==IMAG(y))) ? BOOL_T : BOOL_F;
  2145.     return CPLXP(y) ? BOOL_F : BOOL_T;
  2146.   }
  2147.   if NINUMP(y) {
  2148. # ifdef BIGDIG
  2149.     ASRTGO(NIMP(y), bady);
  2150.     if BIGP(y) return BOOL_F;
  2151. #  ifndef RECKLESS
  2152.     if (!(INEXP(y)))
  2153.     bady: scm_wta(y, (char *)ARG2, s_eq_p);
  2154. #  endif
  2155. # else
  2156. #  ifndef RECKLESS
  2157.     if (!(NIMP(y) && INEXP(y)))
  2158.     bady: scm_wta(y, (char *)ARG2, s_eq_p);
  2159. #  endif
  2160. # endif
  2161.   realint:
  2162.     return (REALP(y) && (((double)INUM(x))==REALPART(y))) ? BOOL_T : BOOL_F;
  2163.   }
  2164. #else
  2165. # ifdef BIGDIG
  2166.   if NINUMP(x) {
  2167.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_eq_p);
  2168.     if INUMP(y) return BOOL_F;
  2169.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2170.     return (0==scm_bigcomp(x, y)) ? BOOL_T : BOOL_F;
  2171.   }
  2172.   if NINUMP(y) {
  2173. #  ifndef RECKLESS
  2174.     if (!(NIMP(y) && BIGP(y)))
  2175.     bady: scm_wta(y, (char *)ARG2, s_eq_p);
  2176. #  endif
  2177.     return BOOL_F;
  2178.   }
  2179. # else
  2180.   ASSERT(INUMP(x), x, ARG1, s_eq_p);
  2181.   ASSERT(INUMP(y), y, ARG2, s_eq_p);
  2182. # endif
  2183. #endif
  2184.   return ((long)x==(long)y) ? BOOL_T : BOOL_F;
  2185. }
  2186.  
  2187.  
  2188.  
  2189. PROC1 (s_less_p, "<?", tc7_rpsubr, scm_less_p);
  2190. #ifdef __STDC__
  2191. SCM
  2192. scm_less_p(SCM x, SCM y)
  2193. #else
  2194. SCM
  2195. scm_less_p(x, y)
  2196.      SCM x;
  2197.      SCM y;
  2198. #endif
  2199. {
  2200. #ifdef FLOATS
  2201.   if NINUMP(x) {
  2202. # ifdef BIGDIG
  2203. #  ifndef RECKLESS
  2204.     if (!(NIMP(x)))
  2205.     badx: scm_wta(x, (char *)ARG1, s_less_p);
  2206. #  endif
  2207.     if BIGP(x) {
  2208.       if INUMP(y) return BIGSIGN(x) ? BOOL_T : BOOL_F;
  2209.       ASRTGO(NIMP(y), bady);
  2210.       if BIGP(y) return (1==scm_bigcomp(x, y)) ? BOOL_T : BOOL_F;
  2211.       ASRTGO(REALP(y), bady);
  2212.       return (scm_big2dbl(x) < REALPART(y)) ? BOOL_T : BOOL_F;
  2213.     }
  2214.     ASRTGO(REALP(x), badx);
  2215. # else
  2216.     ASSERT(NIMP(x) && REALP(x), x, ARG1, s_less_p);
  2217. # endif
  2218.     if (INUMP(y))
  2219.       return (REALPART(x) < ((double)INUM(y))) ? BOOL_T : BOOL_F;
  2220. # ifdef BIGDIG
  2221.     ASRTGO(NIMP(y), bady);
  2222.     if BIGP(y) return (REALPART(x) < scm_big2dbl(y)) ? BOOL_T : BOOL_F;
  2223.     ASRTGO(REALP(y), bady);
  2224. # else
  2225.     ASRTGO(NIMP(y) && REALP(y), bady);
  2226. # endif
  2227.     return (REALPART(x) < REALPART(y)) ? BOOL_T : BOOL_F;
  2228.   }
  2229.   if NINUMP(y) {
  2230. # ifdef BIGDIG
  2231.     ASRTGO(NIMP(y), bady);
  2232.     if BIGP(y) return BIGSIGN(y) ? BOOL_F : BOOL_T;
  2233. #  ifndef RECKLESS
  2234.     if (!(REALP(y)))
  2235.     bady: scm_wta(y, (char *)ARG2, s_less_p);
  2236. #  endif
  2237. # else
  2238. #  ifndef RECKLESS
  2239.     if (!(NIMP(y) && REALP(y)))
  2240.     bady: scm_wta(y, (char *)ARG2, s_less_p);
  2241. #  endif
  2242. # endif
  2243.     return (((double)INUM(x)) < REALPART(y)) ? BOOL_T : BOOL_F;
  2244.   }
  2245. #else
  2246. # ifdef BIGDIG
  2247.   if NINUMP(x) {
  2248.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_less_p);
  2249.     if INUMP(y) return BIGSIGN(x) ? BOOL_T : BOOL_F;
  2250.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2251.     return (1==scm_bigcomp(x, y)) ? BOOL_T : BOOL_F;
  2252.   }
  2253.   if NINUMP(y) {
  2254. #  ifndef RECKLESS
  2255.     if (!(NIMP(y) && BIGP(y)))
  2256.     bady: scm_wta(y, (char *)ARG2, s_less_p);
  2257. #  endif
  2258.     return BIGSIGN(y) ? BOOL_F : BOOL_T;
  2259.   }
  2260. # else
  2261.   ASSERT(INUMP(x), x, ARG1, s_less_p);
  2262.   ASSERT(INUMP(y), y, ARG2, s_less_p);
  2263. # endif
  2264. #endif
  2265.   return ((long)x < (long)y) ? BOOL_T : BOOL_F;
  2266. }
  2267.  
  2268.  
  2269. PROC1 (s_gr_p, ">?", tc7_rpsubr, scm_gr_p);
  2270. #ifdef __STDC__
  2271. SCM
  2272. scm_gr_p(SCM x, SCM y)
  2273. #else
  2274. SCM
  2275. scm_gr_p(x, y)
  2276.      SCM x;
  2277.      SCM y;
  2278. #endif
  2279. {
  2280.   return scm_less_p(y, x);
  2281. }
  2282.  
  2283.  
  2284.  
  2285. PROC1 (s_leq_p, "<=?", tc7_rpsubr, scm_leq_p);
  2286. #ifdef __STDC__
  2287. SCM
  2288. scm_leq_p(SCM x, SCM y)
  2289. #else
  2290. SCM
  2291. scm_leq_p(x, y)
  2292.      SCM x;
  2293.      SCM y;
  2294. #endif
  2295. {
  2296.   return BOOL_NOT(scm_less_p(y, x));
  2297. }
  2298.  
  2299.  
  2300.  
  2301. PROC1 (s_geq_p, ">=?", tc7_rpsubr, scm_geq_p);
  2302. #ifdef __STDC__
  2303. SCM
  2304. scm_geq_p(SCM x, SCM y)
  2305. #else
  2306. SCM
  2307. scm_geq_p(x, y)
  2308.      SCM x;
  2309.      SCM y;
  2310. #endif
  2311. {
  2312.   return BOOL_NOT(scm_less_p(x, y));
  2313. }
  2314.  
  2315.  
  2316.  
  2317. PROC (s_zero_p, "zero?", 1, 0, 0, scm_zero_p);
  2318. #ifdef __STDC__
  2319. SCM
  2320. scm_zero_p(SCM z)
  2321. #else
  2322. SCM
  2323. scm_zero_p(z)
  2324.      SCM z;
  2325. #endif
  2326. {
  2327. #ifdef FLOATS
  2328.   if NINUMP(z) {
  2329. # ifdef BIGDIG
  2330.     ASRTGO(NIMP(z), badz);
  2331.     if BIGP(z) return BOOL_F;
  2332. #  ifndef RECKLESS
  2333.     if (!(INEXP(z)))
  2334.     badz: scm_wta(z, (char *)ARG1, s_zero_p);
  2335. #  endif
  2336. # else
  2337.     ASSERT(NIMP(z) && INEXP(z), z, ARG1, s_zero_p);
  2338. # endif
  2339.     return (z==flo0) ? BOOL_T : BOOL_F;
  2340.   }
  2341. #else
  2342. # ifdef BIGDIG
  2343.   if NINUMP(z) {
  2344.     ASSERT(NIMP(z) && BIGP(z), z, ARG1, s_zero_p);
  2345.     return BOOL_F;
  2346.   }
  2347. # else
  2348.   ASSERT(INUMP(z), z, ARG1, s_zero_p);
  2349. # endif
  2350. #endif
  2351.   return (z==INUM0) ? BOOL_T: BOOL_F;
  2352. }
  2353.  
  2354.  
  2355.  
  2356. PROC (s_positive_p, "positive?", 1, 0, 0, scm_positive_p);
  2357. #ifdef __STDC__
  2358. SCM
  2359. scm_positive_p(SCM x)
  2360. #else
  2361. SCM
  2362. scm_positive_p(x)
  2363.      SCM x;
  2364. #endif
  2365. {
  2366. #ifdef FLOATS
  2367.   if NINUMP(x) {
  2368. # ifdef BIGDIG
  2369.     ASRTGO(NIMP(x), badx);
  2370.     if BIGP(x) return TYP16(x)==tc16_bigpos ? BOOL_T : BOOL_F;
  2371. #  ifndef RECKLESS
  2372.     if (!(REALP(x)))
  2373.     badx: scm_wta(x, (char *)ARG1, s_positive_p);
  2374. #  endif
  2375. # else
  2376.     ASSERT(NIMP(x) && REALP(x), x, ARG1, s_positive_p);
  2377. # endif
  2378.     return (REALPART(x) > 0.0) ? BOOL_T : BOOL_F;
  2379.   }
  2380. #else
  2381. # ifdef BIGDIG
  2382.   if NINUMP(x) {
  2383.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_positive_p);
  2384.     return TYP16(x)==tc16_bigpos ? BOOL_T : BOOL_F;
  2385.   }
  2386. # else
  2387.   ASSERT(INUMP(x), x, ARG1, s_positive_p);
  2388. # endif
  2389. #endif
  2390.   return (x > INUM0) ? BOOL_T : BOOL_F;
  2391. }
  2392.  
  2393.  
  2394.  
  2395. PROC (s_negative_p, "negative?", 1, 0, 0, scm_negative_p);
  2396. #ifdef __STDC__
  2397. SCM
  2398. scm_negative_p(SCM x)
  2399. #else
  2400. SCM
  2401. scm_negative_p(x)
  2402.      SCM x;
  2403. #endif
  2404. {
  2405. #ifdef FLOATS
  2406.   if NINUMP(x) {
  2407. # ifdef BIGDIG
  2408.     ASRTGO(NIMP(x), badx);
  2409.     if BIGP(x) return TYP16(x)==tc16_bigpos ? BOOL_F : BOOL_T;
  2410. #  ifndef RECKLESS
  2411.     if (!(REALP(x)))
  2412.     badx: scm_wta(x, (char *)ARG1, s_negative_p);
  2413. #  endif
  2414. # else
  2415.     ASSERT(NIMP(x) && REALP(x), x, ARG1, s_negative_p);
  2416. # endif
  2417.     return (REALPART(x) < 0.0) ? BOOL_T : BOOL_F;
  2418.   }
  2419. #else
  2420. # ifdef BIGDIG
  2421.   if NINUMP(x) {
  2422.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_negative_p);
  2423.     return (TYP16(x)==tc16_bigneg) ? BOOL_T : BOOL_F;
  2424.   }
  2425. # else
  2426.   ASSERT(INUMP(x), x, ARG1, s_negative_p);
  2427. # endif
  2428. #endif
  2429.   return (x < INUM0) ? BOOL_T : BOOL_F;
  2430. }
  2431.  
  2432.  
  2433. PROC1 (s_max, "max", tc7_asubr, scm_max);
  2434. #ifdef __STDC__
  2435. SCM
  2436. scm_max(SCM x, SCM y)
  2437. #else
  2438. SCM
  2439. scm_max(x, y)
  2440.      SCM x;
  2441.      SCM y;
  2442. #endif
  2443. {
  2444. #ifdef FLOATS
  2445.   double z;
  2446. #endif
  2447.   if UNBNDP(y) {
  2448. #ifndef RECKLESS
  2449.     if (!(NUMBERP(x)))
  2450.       badx: scm_wta(x, (char *)ARG1, s_max);
  2451. #endif
  2452.     return x;
  2453.   }
  2454. #ifdef FLOATS
  2455.   if NINUMP(x) {
  2456. # ifdef BIGDIG
  2457.     ASRTGO(NIMP(x), badx);
  2458.     if BIGP(x) {
  2459.       if INUMP(y) return BIGSIGN(x) ? y : x;
  2460.       ASRTGO(NIMP(y), bady);
  2461.       if BIGP(y) return (1==scm_bigcomp(x, y)) ? y : x;
  2462.       ASRTGO(REALP(y), bady);
  2463.       z = scm_big2dbl(x);
  2464.       return (z < REALPART(y)) ? y : scm_makdbl(z, 0.0);
  2465.     }
  2466.     ASRTGO(REALP(x), badx);
  2467. # else
  2468.     ASSERT(NIMP(x) && REALP(x), x, ARG1, s_max);
  2469. # endif
  2470.     if (INUMP(y))
  2471.       return (REALPART(x) < (z = INUM(y))) ? scm_makdbl(z, 0.0) : x;
  2472. # ifdef BIGDIG
  2473.     ASRTGO(NIMP(y), bady);
  2474.     if (BIGP(y))
  2475.       return (REALPART(x) < (z = scm_big2dbl(y))) ? scm_makdbl(z, 0.0) : x;
  2476.     ASRTGO(REALP(y), bady);
  2477. # else
  2478.     ASRTGO(NIMP(y) && REALP(y), bady);
  2479. # endif
  2480.     return (REALPART(x) < REALPART(y)) ? y : x;
  2481.   }
  2482.   if NINUMP(y) {
  2483. # ifdef BIGDIG
  2484.     ASRTGO(NIMP(y), bady);
  2485.     if BIGP(y) return BIGSIGN(y) ? x : y;
  2486. #  ifndef RECKLESS
  2487.     if (!(REALP(y)))
  2488.     bady: scm_wta(y, (char *)ARG2, s_max);
  2489. #  endif
  2490. # else
  2491. #  ifndef RECKLESS
  2492.     if (!(NIMP(y) && REALP(y)))
  2493.     bady: scm_wta(y, (char *)ARG2, s_max);
  2494. #  endif
  2495. # endif
  2496.     return ((z = INUM(x)) < REALPART(y)) ? y : scm_makdbl(z, 0.0);
  2497.   }
  2498. #else
  2499. # ifdef BIGDIG
  2500.   if NINUMP(x) {
  2501.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_max);
  2502.     if INUMP(y) return BIGSIGN(x) ? y : x;
  2503.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2504.     return (1==scm_bigcomp(x, y)) ? y : x;
  2505.   }
  2506.   if NINUMP(y) {
  2507. #  ifndef RECKLESS
  2508.     if (!(NIMP(y) && BIGP(y)))
  2509.     bady: scm_wta(y, (char *)ARG2, s_max);
  2510. #  endif
  2511.     return BIGSIGN(y) ? x : y;
  2512.   }
  2513. # else
  2514.   ASSERT(INUMP(x), x, ARG1, s_max);
  2515.   ASSERT(INUMP(y), y, ARG2, s_max);
  2516. # endif
  2517. #endif
  2518.   return ((long)x < (long)y) ? y : x;
  2519. }
  2520.  
  2521.  
  2522.  
  2523.  
  2524. PROC1 (s_min, "min", tc7_asubr, scm_min);
  2525. #ifdef __STDC__
  2526. SCM
  2527. scm_min(SCM x, SCM y)
  2528. #else
  2529. SCM
  2530. scm_min(x, y)
  2531.      SCM x;
  2532.      SCM y;
  2533. #endif
  2534. {
  2535. #ifdef FLOATS
  2536.   double z;
  2537. #endif
  2538.   if UNBNDP(y) {
  2539. #ifndef RECKLESS
  2540.     if (!(NUMBERP(x)))
  2541.       badx:scm_wta(x, (char *)ARG1, s_min);
  2542. #endif
  2543.     return x;
  2544.   }
  2545. #ifdef FLOATS
  2546.   if NINUMP(x) {
  2547. # ifdef BIGDIG
  2548.     ASRTGO(NIMP(x), badx);
  2549.     if BIGP(x) {
  2550.       if INUMP(y) return BIGSIGN(x) ? x : y;
  2551.       ASRTGO(NIMP(y), bady);
  2552.       if BIGP(y) return (-1==scm_bigcomp(x, y)) ? y : x;
  2553.       ASRTGO(REALP(y), bady);
  2554.       z = scm_big2dbl(x);
  2555.       return (z > REALPART(y)) ? y : scm_makdbl(z, 0.0);
  2556.     }
  2557.     ASRTGO(REALP(x), badx);
  2558. # else
  2559.     ASSERT(NIMP(x) && REALP(x), x, ARG1, s_min);
  2560. # endif
  2561.     if INUMP(y) return (REALPART(x) > (z = INUM(y))) ? scm_makdbl(z, 0.0) : x;
  2562. # ifdef BIGDIG
  2563.     ASRTGO(NIMP(y), bady);
  2564.     if BIGP(y) return (REALPART(x) > (z = scm_big2dbl(y))) ? scm_makdbl(z, 0.0) : x;
  2565.     ASRTGO(REALP(y), bady);
  2566. # else
  2567.     ASRTGO(NIMP(y) && REALP(y), bady);
  2568. # endif
  2569.     return (REALPART(x) > REALPART(y)) ? y : x;
  2570.   }
  2571.   if NINUMP(y) {
  2572. # ifdef BIGDIG
  2573.     ASRTGO(NIMP(y), bady);
  2574.     if BIGP(y) return BIGSIGN(y) ? y : x;
  2575. #  ifndef RECKLESS
  2576.     if (!(REALP(y)))
  2577.     bady: scm_wta(y, (char *)ARG2, s_min);
  2578. #  endif
  2579. # else
  2580. #  ifndef RECKLESS
  2581.     if (!(NIMP(y) && REALP(y)))
  2582.     bady: scm_wta(y, (char *)ARG2, s_min);
  2583. #  endif
  2584. # endif
  2585.     return ((z = INUM(x)) > REALPART(y)) ? y : scm_makdbl(z, 0.0);
  2586.   }
  2587. #else
  2588. # ifdef BIGDIG
  2589.   if NINUMP(x) {
  2590.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_min);
  2591.     if INUMP(y) return BIGSIGN(x) ? x : y;
  2592.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2593.     return (-1==scm_bigcomp(x, y)) ? y : x;
  2594.   }
  2595.   if NINUMP(y) {
  2596. #  ifndef RECKLESS
  2597.     if (!(NIMP(y) && BIGP(y)))
  2598.     bady: scm_wta(y, (char *)ARG2, s_min);
  2599. #  endif
  2600.     return BIGSIGN(y) ? y : x;
  2601.   }
  2602. # else
  2603.   ASSERT(INUMP(x), x, ARG1, s_min);
  2604.   ASSERT(INUMP(y), y, ARG2, s_min);
  2605. # endif
  2606. #endif
  2607.   return ((long)x > (long)y) ? y : x;
  2608. }
  2609.  
  2610.  
  2611.  
  2612.  
  2613. PROC1 (s_sum, "+", tc7_asubr, scm_sum);
  2614. #ifdef __STDC__
  2615. SCM
  2616. scm_sum(SCM x, SCM y)
  2617. #else
  2618. SCM
  2619. scm_sum(x, y)
  2620.      SCM x;
  2621.      SCM y;
  2622. #endif
  2623. {
  2624.   if UNBNDP(y) {
  2625.     if UNBNDP(x) return INUM0;
  2626. #ifndef RECKLESS
  2627.     if (!(NUMBERP(x)))
  2628.     badx: scm_wta(x, (char *)ARG1, s_sum);
  2629. #endif
  2630.     return x;
  2631.   }
  2632. #ifdef FLOATS
  2633.   if NINUMP(x) {
  2634.     SCM t;
  2635. # ifdef BIGDIG
  2636.     ASRTGO(NIMP(x), badx);
  2637.     if BIGP(x) {
  2638.       if INUMP(y) {t = x; x = y; y = t; goto intbig;}
  2639.       ASRTGO(NIMP(y), bady);
  2640.       if BIGP(y) {
  2641.     if (NUMDIGS(x) > NUMDIGS(y)) {t = x; x = y; y = t;}
  2642.     return scm_addbig(BDIGITS(x), NUMDIGS(x), BIGSIGN(x), y, 0);
  2643.       }
  2644.       ASRTGO(INEXP(y), bady);
  2645.     bigreal: return scm_makdbl(scm_big2dbl(x)+REALPART(y), CPLXP(y)?IMAG(y):0.0);
  2646.     }
  2647.     ASRTGO(INEXP(x), badx);
  2648. # else
  2649.     ASRTGO(NIMP(x) && INEXP(x), badx);
  2650. # endif
  2651.     if INUMP(y) {t = x; x = y; y = t; goto intreal;}
  2652. # ifdef BIGDIG
  2653.     ASRTGO(NIMP(y), bady);
  2654.     if BIGP(y) {t = x; x = y; y = t; goto bigreal;}
  2655. #  ifndef RECKLESS
  2656.     else if (!(INEXP(y)))
  2657.     bady: scm_wta(y, (char *)ARG2, s_sum);
  2658. #  endif
  2659. # else
  2660. #  ifndef RECKLESS
  2661.     if (!(NIMP(y) && INEXP(y)))
  2662.     bady: scm_wta(y, (char *)ARG2, s_sum);
  2663. #  endif
  2664. # endif
  2665.     { double i = 0.0;
  2666.       if CPLXP(x) i = IMAG(x);
  2667.       if CPLXP(y) i += IMAG(y);
  2668.       return scm_makdbl(REALPART(x)+REALPART(y), i); }
  2669.   }
  2670.   if NINUMP(y) {
  2671. # ifdef BIGDIG
  2672.     ASRTGO(NIMP(y), bady);
  2673.     if BIGP(y)
  2674.     intbig: {
  2675. #  ifndef DIGSTOOBIG
  2676.       long z = scm_pseudolong(INUM(x));
  2677.       return scm_addbig((BIGDIG *)&z, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0);
  2678. #  else
  2679.       BIGDIG zdigs[DIGSPERLONG];
  2680.       scm_longdigs(INUM(x), zdigs);
  2681.       return scm_addbig(zdigs, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0);
  2682. #  endif
  2683.     }
  2684.     ASRTGO(INEXP(y), bady);
  2685. # else
  2686.     ASRTGO(NIMP(y) && INEXP(y), bady);
  2687. # endif
  2688.   intreal: return scm_makdbl(INUM(x)+REALPART(y), CPLXP(y)?IMAG(y):0.0);
  2689.   }
  2690. #else
  2691. # ifdef BIGDIG
  2692.   if NINUMP(x) {
  2693.     SCM t;
  2694.     ASRTGO(NIMP(x) && BIGP(x), badx);
  2695.     if INUMP(y) {t = x; x = y; y = t; goto intbig;}
  2696.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2697.     if (NUMDIGS(x) > NUMDIGS(y)) {t = x; x = y; y = t;}
  2698.     return scm_addbig(BDIGITS(x), NUMDIGS(x), BIGSIGN(x), y, 0);
  2699.   }
  2700.   if NINUMP(y) {
  2701. #  ifndef RECKLESS
  2702.     if (!(NIMP(y) && BIGP(y)))
  2703.     bady: scm_wta(y, (char *)ARG2, s_sum);
  2704. #  endif
  2705.   intbig: {
  2706. #  ifndef DIGSTOOBIG
  2707.     long z = scm_pseudolong(INUM(x));
  2708.     return scm_addbig(&z, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0);
  2709. #  else
  2710.     BIGDIG zdigs[DIGSPERLONG];
  2711.     scm_longdigs(INUM(x), zdigs);
  2712.     return scm_addbig(zdigs, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0);
  2713. #  endif
  2714.   }
  2715.   }
  2716. # else
  2717.   ASRTGO(INUMP(x), badx);
  2718.   ASSERT(INUMP(y), y, ARG2, s_sum);
  2719. # endif
  2720. #endif
  2721.   x = INUM(x)+INUM(y);
  2722.   if FIXABLE(x) return MAKINUM(x);
  2723. #ifdef BIGDIG
  2724.   return scm_long2big(x);
  2725. #else
  2726. # ifdef FLOATS
  2727.   return scm_makdbl((double)x, 0.0);
  2728. # else
  2729.   scm_wta(y, (char *)OVFLOW, s_sum);
  2730.   return UNSPECIFIED;
  2731. # endif
  2732. #endif
  2733. }
  2734.  
  2735.  
  2736.  
  2737.  
  2738. PROC1 (s_difference, "-", tc7_asubr, scm_difference);
  2739. #ifdef __STDC__
  2740. SCM
  2741. scm_difference(SCM x, SCM y)
  2742. #else
  2743. SCM
  2744. scm_difference(x, y)
  2745.      SCM x;
  2746.      SCM y;
  2747. #endif
  2748. {
  2749. #ifdef FLOATS
  2750.   if NINUMP(x) {
  2751. # ifndef RECKLESS
  2752.     if (!(NIMP(x)))
  2753.     badx: scm_wta(x, (char *)ARG1, s_difference);
  2754. # endif
  2755.     if UNBNDP(y) {
  2756. # ifdef BIGDIG
  2757.       if BIGP(x) {
  2758.     x = scm_copybig(x, !BIGSIGN(x));
  2759.     return NUMDIGS(x) * BITSPERDIG/CHAR_BIT <= sizeof(SCM) ?
  2760.       scm_big2inum(x, NUMDIGS(x)) : x;
  2761.       }
  2762. # endif
  2763.       ASRTGO(INEXP(x), badx);
  2764.       return scm_makdbl(-REALPART(x), CPLXP(x)?-IMAG(x):0.0);
  2765.     }
  2766.     if INUMP(y) return scm_sum(x, MAKINUM(-INUM(y)));
  2767. # ifdef BIGDIG
  2768.     ASRTGO(NIMP(y), bady);
  2769.     if BIGP(x) {
  2770.       if BIGP(y) return (NUMDIGS(x) < NUMDIGS(y)) ?
  2771.     scm_addbig(BDIGITS(x), NUMDIGS(x), BIGSIGN(x), y, 0x0100) :
  2772.       scm_addbig(BDIGITS(y), NUMDIGS(y), BIGSIGN(y) ^ 0x0100, x, 0);
  2773.       ASRTGO(INEXP(y), bady);
  2774.       return scm_makdbl(scm_big2dbl(x)-REALPART(y), CPLXP(y)?-IMAG(y):0.0);
  2775.     }
  2776.     ASRTGO(INEXP(x), badx);
  2777.     if BIGP(y) return scm_makdbl(REALPART(x)-scm_big2dbl(y), CPLXP(x)?IMAG(x):0.0);
  2778.     ASRTGO(INEXP(y), bady);
  2779. # else
  2780.     ASRTGO(INEXP(x), badx);
  2781.     ASRTGO(NIMP(y) && INEXP(y), bady);
  2782. # endif
  2783.     if CPLXP(x)
  2784.       if CPLXP(y)
  2785.     return scm_makdbl(REAL(x)-REAL(y), IMAG(x)-IMAG(y));
  2786.       else
  2787.     return scm_makdbl(REAL(x)-REALPART(y), IMAG(x));
  2788.     return scm_makdbl(REALPART(x)-REALPART(y), CPLXP(y)?-IMAG(y):0.0);
  2789.   }
  2790.   if UNBNDP(y) {x = -INUM(x); goto checkx;}
  2791.   if NINUMP(y) {
  2792. # ifdef BIGDIG
  2793.     ASRTGO(NIMP(y), bady);
  2794.     if BIGP(y) {
  2795. #  ifndef DIGSTOOBIG
  2796.       long z = scm_pseudolong(INUM(x));
  2797.       return scm_addbig((BIGDIG *)&z, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0x0100);
  2798. #  else
  2799.       BIGDIG zdigs[DIGSPERLONG];
  2800.       scm_longdigs(INUM(x), zdigs);
  2801.       return scm_addbig(zdigs, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0x0100);
  2802. #  endif
  2803.     }
  2804. #  ifndef RECKLESS
  2805.     if (!(INEXP(y)))
  2806.     bady: scm_wta(y, (char *)ARG2, s_difference);
  2807. #  endif
  2808. # else
  2809. #  ifndef RECKLESS
  2810.     if (!(NIMP(y) && INEXP(y)))
  2811.     bady: scm_wta(y, (char *)ARG2, s_difference);
  2812. #  endif
  2813. # endif
  2814.     return scm_makdbl(INUM(x)-REALPART(y), CPLXP(y)?-IMAG(y):0.0);
  2815.   }
  2816. #else
  2817. # ifdef BIGDIG
  2818.   if NINUMP(x) {
  2819.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_difference);
  2820.     if UNBNDP(y) {
  2821.       x = scm_copybig(x, !BIGSIGN(x));
  2822.       return NUMDIGS(x) * BITSPERDIG/CHAR_BIT <= sizeof(SCM) ?
  2823.     scm_big2inum(x, NUMDIGS(x)) : x;
  2824.     }
  2825.     if INUMP(y) {
  2826. #  ifndef DIGSTOOBIG
  2827.       long z = scm_pseudolong(INUM(y));
  2828.       return scm_addbig(&z, DIGSPERLONG, (y < 0) ? 0 : 0x0100, x, 0);
  2829. #  else
  2830.       BIGDIG zdigs[DIGSPERLONG];
  2831.       scm_longdigs(INUM(x), zdigs);
  2832.       return scm_addbig(zdigs, DIGSPERLONG, (y < 0) ? 0 : 0x0100, x, 0);
  2833. #  endif
  2834.     }
  2835.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2836.     return (NUMDIGS(x) < NUMDIGS(y)) ?
  2837.       scm_addbig(BDIGITS(x), NUMDIGS(x), BIGSIGN(x), y, 0x0100) :
  2838.     scm_addbig(BDIGITS(y), NUMDIGS(y), BIGSIGN(y) ^ 0x0100, x, 0);
  2839.   }
  2840.   if UNBNDP(y) {x = -INUM(x); goto checkx;}
  2841.   if NINUMP(y) {
  2842. #  ifndef RECKLESS
  2843.     if (!(NIMP(y) && BIGP(y)))
  2844.     bady: scm_wta(y, (char *)ARG2, s_difference);
  2845. #  endif
  2846.     {
  2847. #  ifndef DIGSTOOBIG
  2848.       long z = scm_pseudolong(INUM(x));
  2849.       return scm_addbig(&z, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0x0100);
  2850. #  else
  2851.       BIGDIG zdigs[DIGSPERLONG];
  2852.       scm_longdigs(INUM(x), zdigs);
  2853.       return scm_addbig(zdigs, DIGSPERLONG, (x < 0) ? 0x0100 : 0, y, 0x0100);
  2854. #  endif
  2855.     }
  2856.   }
  2857. # else
  2858.   ASSERT(INUMP(x), x, ARG1, s_difference);
  2859.   if UNBNDP(y) {x = -INUM(x); goto checkx;}
  2860.   ASSERT(INUMP(y), y, ARG2, s_difference);
  2861. # endif
  2862. #endif
  2863.   x = INUM(x)-INUM(y);
  2864.  checkx:
  2865.   if FIXABLE(x) return MAKINUM(x);
  2866. #ifdef BIGDIG
  2867.   return scm_long2big(x);
  2868. #else
  2869. # ifdef FLOATS
  2870.   return scm_makdbl((double)x, 0.0);
  2871. # else
  2872.   scm_wta(y, (char *)OVFLOW, s_difference);
  2873.   return UNSPECIFIED;
  2874. # endif
  2875. #endif
  2876. }
  2877.  
  2878.  
  2879.  
  2880.  
  2881. PROC1 (s_product, "*", tc7_asubr, scm_product);
  2882. #ifdef __STDC__
  2883. SCM
  2884. scm_product(SCM x, SCM y)
  2885. #else
  2886. SCM
  2887. scm_product(x, y)
  2888.      SCM x;
  2889.      SCM y;
  2890. #endif
  2891. {
  2892.   if UNBNDP(y) {
  2893.     if UNBNDP(x) return MAKINUM(1L);
  2894. #ifndef RECKLESS
  2895.     if (!(NUMBERP(x)))
  2896.     badx: scm_wta(x, (char *)ARG1, s_product);
  2897. #endif
  2898.     return x;
  2899.   }
  2900. #ifdef FLOATS
  2901.   if NINUMP(x) {
  2902.     SCM t;
  2903. # ifdef BIGDIG
  2904.     ASRTGO(NIMP(x), badx);
  2905.     if BIGP(x) {
  2906.       if INUMP(y) {t = x; x = y; y = t; goto intbig;}
  2907.       ASRTGO(NIMP(y), bady);
  2908.       if BIGP(y) return scm_mulbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  2909.                    BIGSIGN(x) ^ BIGSIGN(y));
  2910.       ASRTGO(INEXP(y), bady);
  2911.     bigreal: {
  2912.       double bg = scm_big2dbl(x);
  2913.       return scm_makdbl(bg*REALPART(y), CPLXP(y)?bg*IMAG(y):0.0); }
  2914.     }
  2915.     ASRTGO(INEXP(x), badx);
  2916. # else
  2917.     ASRTGO(NIMP(x) && INEXP(x), badx);
  2918. # endif
  2919.     if INUMP(y) {t = x; x = y; y = t; goto intreal;}
  2920. # ifdef BIGDIG
  2921.     ASRTGO(NIMP(y), bady);
  2922.     if BIGP(y) {t = x; x = y; y = t; goto bigreal;}
  2923. #  ifndef RECKLESS
  2924.     else if (!(INEXP(y)))
  2925.     bady: scm_wta(y, (char *)ARG2, s_product);
  2926. #  endif
  2927. # else
  2928. #  ifndef RECKLESS
  2929.     if (!(NIMP(y) && INEXP(y)))
  2930.     bady: scm_wta(y, (char *)ARG2, s_product);
  2931. #  endif
  2932. # endif
  2933.     if CPLXP(x)
  2934.       if CPLXP(y)
  2935.     return scm_makdbl(REAL(x)*REAL(y)-IMAG(x)*IMAG(y),
  2936.               REAL(x)*IMAG(y)+IMAG(x)*REAL(y));
  2937.       else
  2938.     return scm_makdbl(REAL(x)*REALPART(y), IMAG(x)*REALPART(y));
  2939.     return scm_makdbl(REALPART(x)*REALPART(y),
  2940.               CPLXP(y)?REALPART(x)*IMAG(y):0.0);
  2941.   }
  2942.   if NINUMP(y) {
  2943. # ifdef BIGDIG
  2944.     ASRTGO(NIMP(y), bady);
  2945.     if BIGP(y) {
  2946.     intbig: if (INUM0==x) return x; if (MAKINUM(1L)==x) return y;
  2947.       {
  2948. #  ifndef DIGSTOOBIG
  2949.     long z = scm_pseudolong(INUM(x));
  2950.     return scm_mulbig((BIGDIG *)&z, DIGSPERLONG, BDIGITS(y), NUMDIGS(y),
  2951.               BIGSIGN(y) ? (x>0) : (x<0));
  2952. #  else
  2953.     BIGDIG zdigs[DIGSPERLONG];
  2954.     scm_longdigs(INUM(x), zdigs);
  2955.     return scm_mulbig(zdigs, DIGSPERLONG, BDIGITS(y), NUMDIGS(y),
  2956.               BIGSIGN(y) ? (x>0) : (x<0));
  2957. #  endif
  2958.       }
  2959.     }
  2960.     ASRTGO(INEXP(y), bady);
  2961. # else
  2962.     ASRTGO(NIMP(y) && INEXP(y), bady);
  2963. # endif
  2964.   intreal: return scm_makdbl(INUM(x)*REALPART(y), CPLXP(y)?INUM(x)*IMAG(y):0.0);
  2965.   }
  2966. #else
  2967. # ifdef BIGDIG
  2968.   if NINUMP(x) {
  2969.     ASRTGO(NIMP(x) && BIGP(x), badx);
  2970.     if INUMP(y) {SCM t = x; x = y; y = t; goto intbig;}
  2971.     ASRTGO(NIMP(y) && BIGP(y), bady);
  2972.     return scm_mulbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  2973.               BIGSIGN(x) ^ BIGSIGN(y));
  2974.   }
  2975.   if NINUMP(y) {
  2976. #  ifndef RECKLESS
  2977.     if (!(NIMP(y) && BIGP(y)))
  2978.     bady: scm_wta(y, (char *)ARG2, s_product);
  2979. #  endif
  2980.   intbig: if (INUM0==x) return x; if (MAKINUM(1L)==x) return y;
  2981.     {
  2982. #  ifndef DIGSTOOBIG
  2983.       long z = scm_pseudolong(INUM(x));
  2984.       return scm_mulbig(&z, DIGSPERLONG, BDIGITS(y), NUMDIGS(y),
  2985.             BIGSIGN(y) ? (x>0) : (x<0));
  2986. #  else
  2987.       BIGDIG zdigs[DIGSPERLONG];
  2988.       scm_longdigs(INUM(x), zdigs);
  2989.       return scm_mulbig(zdigs, DIGSPERLONG, BDIGITS(y), NUMDIGS(y),
  2990.             BIGSIGN(y) ? (x>0) : (x<0));
  2991. #  endif
  2992.     }
  2993.   }
  2994. # else
  2995.   ASRTGO(INUMP(x), badx);
  2996.   ASSERT(INUMP(y), y, ARG2, s_product);
  2997. # endif
  2998. #endif
  2999.   {
  3000.     long i, j, k;
  3001.     i = INUM(x);
  3002.     if (0==i) return x;
  3003.     j = INUM(y);
  3004.     k = i * j;
  3005.     y = MAKINUM(k);
  3006.     if (k != INUM(y) || k/i != j)
  3007. #ifdef BIGDIG
  3008.       { int sgn = (i < 0) ^ (j < 0);
  3009. # ifndef DIGSTOOBIG
  3010.     i = scm_pseudolong(i);
  3011.     j = scm_pseudolong(j);
  3012.     return scm_mulbig((BIGDIG *)&i, DIGSPERLONG,
  3013.               (BIGDIG *)&j, DIGSPERLONG, sgn);
  3014. # else /* DIGSTOOBIG */
  3015.     BIGDIG idigs[DIGSPERLONG];
  3016.     BIGDIG jdigs[DIGSPERLONG];
  3017.     scm_longdigs(i, idigs);
  3018.     scm_longdigs(j, jdigs);
  3019.     return scm_mulbig(idigs, DIGSPERLONG, jdigs, DIGSPERLONG, sgn);
  3020. # endif
  3021.       }
  3022. #else
  3023. # ifdef FLOATS
  3024.     return scm_makdbl(((double)i)*((double)j), 0.0);
  3025. # else
  3026.     scm_wta(y, (char *)OVFLOW, s_product);
  3027. # endif
  3028. #endif
  3029.     return y;
  3030.   }
  3031. }
  3032.  
  3033.  
  3034. #ifdef __STDC__
  3035. double
  3036. scm_num2dbl (SCM a, char * why)
  3037. #else
  3038. double
  3039. scm_num2dbl (a, why)
  3040.      SCM a;
  3041.      char * why;
  3042. #endif
  3043. {
  3044.   if (INUMP (a))
  3045.     return (double) INUM (a);
  3046. #ifdef FLOATS
  3047.   ASSERT (NIMP (a), a, "wrong type argument", why);
  3048.   if (REALP (a))
  3049.     return (REALPART (a));
  3050. #endif
  3051. #ifdef BIGDIG
  3052.   return scm_big2dbl (a);
  3053. #endif
  3054.   ASSERT (0, a, "wrong type argument", why);
  3055.   return UNSPECIFIED;
  3056. }
  3057.  
  3058.  
  3059. PROC (s_fuck, "fuck", 1, 0, 0, scm_fuck);
  3060. #ifdef __STDC__
  3061. SCM
  3062. scm_fuck (SCM a)
  3063. #else
  3064. SCM
  3065. scm_fuck (a)
  3066.      SCM a;
  3067. #endif
  3068. {
  3069.   return scm_makdbl (scm_num2dbl (a, "just because"), 0.0);
  3070. }
  3071.  
  3072. PROC1 (s_divide, "/", tc7_asubr, scm_divide);
  3073. #ifdef __STDC__
  3074. SCM
  3075. scm_divide(SCM x, SCM y)
  3076. #else
  3077. SCM
  3078. scm_divide(x, y)
  3079.      SCM x;
  3080.      SCM y;
  3081. #endif
  3082. {
  3083. #ifdef FLOATS
  3084.   double d, r, i, a;
  3085.   if NINUMP(x) {
  3086. # ifndef RECKLESS
  3087.     if (!(NIMP(x)))
  3088.     badx: scm_wta(x, (char *)ARG1, s_divide);
  3089. # endif
  3090.     if UNBNDP(y) {
  3091. # ifdef BIGDIG
  3092.       if BIGP(x) return scm_makdbl(1.0/scm_big2dbl(x), 0.0);
  3093. # endif
  3094.       ASRTGO(INEXP(x), badx);
  3095.       if REALP(x) return scm_makdbl(1.0/REALPART(x), 0.0);
  3096.       r = REAL(x);  i = IMAG(x);  d = r*r+i*i;
  3097.       return scm_makdbl(r/d, -i/d);
  3098.     }
  3099. # ifdef BIGDIG
  3100.     if BIGP(x) {
  3101.       SCM z;
  3102.       if INUMP(y) {
  3103.         z = INUM(y);
  3104.         ASSERT(z, y, OVFLOW, s_divide);
  3105.     if (1==z) return x;
  3106.         if (z < 0) z = -z;
  3107.         if (z < BIGRAD) {
  3108.           SCM w = scm_copybig(x, BIGSIGN(x) ? (y>0) : (y<0));
  3109.           return scm_divbigdig(BDIGITS(w), NUMDIGS(w), (BIGDIG)z) ?
  3110.         scm_makdbl(scm_big2dbl(x)/INUM(y), 0.0) : scm_normbig(w);
  3111.     }
  3112. #  ifndef DIGSTOOBIG
  3113.         z = scm_pseudolong(z);
  3114.         z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), (BIGDIG *)&z, DIGSPERLONG,
  3115.               BIGSIGN(x) ? (y>0) : (y<0), 3);
  3116. #  else
  3117.     { BIGDIG zdigs[DIGSPERLONG];
  3118.       scm_longdigs(z, zdigs);
  3119.       z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), zdigs, DIGSPERLONG,
  3120.                 BIGSIGN(x) ? (y>0) : (y<0), 3);}
  3121. #  endif
  3122.         return z ? z : scm_makdbl(scm_big2dbl(x)/INUM(y), 0.0);
  3123.       }
  3124.       ASRTGO(NIMP(y), bady);
  3125.       if BIGP(y) {
  3126.     z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  3127.               BIGSIGN(x) ^ BIGSIGN(y), 3);
  3128.     return z ? z : scm_makdbl(scm_big2dbl(x)/scm_big2dbl(y), 0.0);
  3129.       }
  3130.       ASRTGO(INEXP(y), bady);
  3131.       if REALP(y) return scm_makdbl(scm_big2dbl(x)/REALPART(y), 0.0);
  3132.       a = scm_big2dbl(x);
  3133.       goto complex_div;
  3134.     }
  3135. # endif
  3136.     ASRTGO(INEXP(x), badx);
  3137.     if INUMP(y) {d = INUM(y); goto basic_div;}
  3138. # ifdef BIGDIG
  3139.     ASRTGO(NIMP(y), bady);
  3140.     if BIGP(y) {d = scm_big2dbl(y); goto basic_div;}
  3141.     ASRTGO(INEXP(y), bady);
  3142. # else
  3143.     ASRTGO(NIMP(y) && INEXP(y), bady);
  3144. # endif
  3145.     if REALP(y) {
  3146.       d = REALPART(y);
  3147.     basic_div: return scm_makdbl(REALPART(x)/d, CPLXP(x)?IMAG(x)/d:0.0);
  3148.     }
  3149.     a = REALPART(x);
  3150.     if REALP(x) goto complex_div;
  3151.     r = REAL(y);  i = IMAG(y);  d = r*r+i*i;
  3152.     return scm_makdbl((a*r+IMAG(x)*i)/d, (IMAG(x)*r-a*i)/d);
  3153.   }
  3154.   if UNBNDP(y) {
  3155.     if ((MAKINUM(1L)==x) || (MAKINUM(-1L)==x)) return x;
  3156.     return scm_makdbl(1.0/((double)INUM(x)), 0.0);
  3157.   }
  3158.   if NINUMP(y) {
  3159. # ifdef BIGDIG
  3160.     ASRTGO(NIMP(y), bady);
  3161.     if BIGP(y) return scm_makdbl(INUM(x)/scm_big2dbl(y), 0.0);
  3162. #  ifndef RECKLESS
  3163.     if (!(INEXP(y)))
  3164.     bady: scm_wta(y, (char *)ARG2, s_divide);
  3165. #  endif
  3166. # else
  3167. #  ifndef RECKLESS
  3168.     if (!(NIMP(y) && INEXP(y)))
  3169.     bady: scm_wta(y, (char *)ARG2, s_divide);
  3170. #  endif
  3171. # endif
  3172.     if (REALP(y))
  3173.       return scm_makdbl(INUM(x)/REALPART(y), 0.0);
  3174.     a = INUM(x);
  3175.   complex_div:
  3176.     r = REAL(y);  i = IMAG(y);  d = r*r+i*i;
  3177.     return scm_makdbl((a*r)/d, (-a*i)/d);
  3178.   }
  3179. #else
  3180. # ifdef BIGDIG
  3181.   if NINUMP(x) {
  3182.     SCM z;
  3183.     ASSERT(NIMP(x) && BIGP(x), x, ARG1, s_divide);
  3184.     if UNBNDP(y) goto ov;
  3185.     if INUMP(y) {
  3186.       z = INUM(y);
  3187.       if (!z) goto ov;
  3188.       if (1==z) return x;
  3189.       if (z < 0) z = -z;
  3190.       if (z < BIGRAD) {
  3191.         SCM w = scm_copybig(x, BIGSIGN(x) ? (y>0) : (y<0));
  3192.         if (scm_divbigdig(BDIGITS(w), NUMDIGS(w), (BIGDIG)z)) goto ov;
  3193.         return w;
  3194.       }
  3195. #  ifndef DIGSTOOBIG
  3196.       z = scm_pseudolong(z);
  3197.       z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), &z, DIGSPERLONG,
  3198.             BIGSIGN(x) ? (y>0) : (y<0), 3);
  3199. #  else
  3200.       { BIGDIG zdigs[DIGSPERLONG];
  3201.     scm_longdigs(z, zdigs);
  3202.     z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), zdigs, DIGSPERLONG,
  3203.               BIGSIGN(x) ? (y>0) : (y<0), 3);}
  3204. #  endif
  3205.     } else {
  3206.       ASRTGO(NIMP(y) && BIGP(y), bady);
  3207.       z = scm_divbigbig(BDIGITS(x), NUMDIGS(x), BDIGITS(y), NUMDIGS(y),
  3208.             BIGSIGN(x) ^ BIGSIGN(y), 3);
  3209.     }
  3210.     if (!z) goto ov;
  3211.     return z;
  3212.   }
  3213.   if UNBNDP(y) {
  3214.     if ((MAKINUM(1L)==x) || (MAKINUM(-1L)==x)) return x;
  3215.     goto ov;
  3216.   }
  3217.   if NINUMP(y) {
  3218. #  ifndef RECKLESS
  3219.     if (!(NIMP(y) && BIGP(y)))
  3220.     bady: scm_wta(y, (char *)ARG2, s_divide);
  3221. #  endif
  3222.     goto ov;
  3223.   }
  3224. # else
  3225.   ASSERT(INUMP(x), x, ARG1, s_divide);
  3226.   if UNBNDP(y) {
  3227.     if ((MAKINUM(1L)==x) || (MAKINUM(-1L)==x)) return x;
  3228.     goto ov;
  3229.   }
  3230.   ASSERT(INUMP(y), y, ARG2, s_divide);
  3231. # endif
  3232. #endif
  3233.   {
  3234.     long z = INUM(y);
  3235.     if ((0==z) || INUM(x)%z) goto ov;
  3236.     z = INUM(x)/z;
  3237.     if FIXABLE(z) return MAKINUM(z);
  3238. #ifdef BIGDIG
  3239.     return scm_long2big(z);
  3240. #endif
  3241. #ifdef FLOATS
  3242.   ov: return scm_makdbl(((double)INUM(x))/((double)INUM(y)), 0.0);
  3243. #else
  3244.   ov: scm_wta(x, (char *)OVFLOW, s_divide);
  3245.     return UNSPECIFIED;
  3246. #endif
  3247.   }
  3248. }
  3249.  
  3250.  
  3251.  
  3252.  
  3253. #ifdef FLOATS
  3254. PROC1 (s_asinh, "$asinh", tc7_cxr, (SCM (*)()) scm_asinh);
  3255. #ifdef __STDC__
  3256. double
  3257. scm_asinh(double x)
  3258. #else
  3259. double
  3260. scm_asinh(x)
  3261.      double x;
  3262. #endif
  3263. {
  3264.   return log(x+sqrt(x*x+1));
  3265. }
  3266.  
  3267.  
  3268.  
  3269.  
  3270. PROC1 (s_acosh, "$acosh", tc7_cxr, (SCM (*)()) scm_acosh);
  3271. #ifdef __STDC__
  3272. double
  3273. scm_acosh(double x)
  3274. #else
  3275. double
  3276. scm_acosh(x)
  3277.      double x;
  3278. #endif
  3279. {
  3280.   return log(x+sqrt(x*x-1));
  3281. }
  3282.  
  3283.  
  3284.  
  3285.  
  3286. PROC1 (s_atanh, "$atanh", tc7_cxr, (SCM (*)()) scm_atanh);
  3287. #ifdef __STDC__
  3288. double
  3289. scm_atanh(double x)
  3290. #else
  3291. double
  3292. scm_atanh(x)
  3293.      double x;
  3294. #endif
  3295. {
  3296.   return 0.5*log((1+x)/(1-x));
  3297. }
  3298.  
  3299.  
  3300.  
  3301.  
  3302. PROC1 (s_truncate, "truncate", tc7_cxr, (SCM (*)()) scm_truncate);
  3303. #ifdef __STDC__
  3304. double
  3305. scm_truncate(double x)
  3306. #else
  3307. double
  3308. scm_truncate(x)
  3309.      double x;
  3310. #endif
  3311. {
  3312.   if (x < 0.0) return -floor(-x);
  3313.   return floor(x);
  3314. }
  3315.  
  3316.  
  3317.  
  3318. PROC1 (s_round, "round", tc7_cxr, (SCM (*)()) scm_round);
  3319. #ifdef __STDC__
  3320. double
  3321. scm_round(double x)
  3322. #else
  3323. double
  3324. scm_round(x)
  3325.      double x;
  3326. #endif
  3327. {
  3328.   double plus_half = x + 0.5;
  3329.   double result = floor(plus_half);
  3330.   /* Adjust so that the scm_round is towards even.  */
  3331.   return (plus_half == result && plus_half / 2 != floor(plus_half / 2))
  3332.     ? result - 1 : result;
  3333. }
  3334.  
  3335.  
  3336.  
  3337. PROC1 (s_exact_to_inexact, "exact->inexact", tc7_cxr, (SCM (*)()) scm_exact_to_inexact);
  3338. #ifdef __STDC__
  3339. double
  3340. scm_exact_to_inexact(double z)
  3341. #else
  3342. double
  3343. scm_exact_to_inexact(z)
  3344.      double z;
  3345. #endif
  3346. {
  3347.   return z;
  3348. }
  3349.  
  3350.  
  3351. PROC1 (s_i_floor, "floor", tc7_cxr, (SCM (*)()) floor);
  3352. PROC1 (s_i_ceil, "ceiling", tc7_cxr, (SCM (*)()) ceil);
  3353. PROC1 (s_i_sqrt, "$sqrt", tc7_cxr, (SCM (*)())sqrt);
  3354. PROC1 (s_i_abs, "$abs", tc7_cxr, (SCM (*)())fabs);
  3355. PROC1 (s_i_exp, "$exp", tc7_cxr, (SCM (*)())exp);
  3356. PROC1 (s_i_log, "$log", tc7_cxr, (SCM (*)())log);
  3357. PROC1 (s_i_sin, "$sin", tc7_cxr, (SCM (*)())sin);
  3358. PROC1 (s_i_cos, "$cos", tc7_cxr, (SCM (*)())cos);
  3359. PROC1 (s_i_tan, "$tan", tc7_cxr, (SCM (*)())tan);
  3360. PROC1 (s_i_asin, "$asin", tc7_cxr, (SCM (*)())asin);
  3361. PROC1 (s_i_acos, "$acos", tc7_cxr, (SCM (*)())acos);
  3362. PROC1 (s_i_atan, "$atan", tc7_cxr, (SCM (*)())atan);
  3363. PROC1 (s_i_sinh, "$sinh", tc7_cxr, (SCM (*)())sinh);
  3364. PROC1 (s_i_cosh, "$cosh", tc7_cxr, (SCM (*)())cosh);
  3365. PROC1 (s_i_tanh, "$tanh", tc7_cxr, (SCM (*)())tanh);
  3366.  
  3367. struct dpair {double x, y;};
  3368.  
  3369. void scm_two_doubles(z1, z2, sstring, xy)
  3370.      SCM z1, z2;
  3371.      char *sstring;
  3372.      struct dpair *xy;
  3373. {
  3374.   if INUMP(z1) xy->x = INUM(z1);
  3375.   else {
  3376. # ifdef BIGDIG
  3377.     ASRTGO(NIMP(z1), badz1);
  3378.     if BIGP(z1) xy->x = scm_big2dbl(z1);
  3379.     else {
  3380. #  ifndef RECKLESS
  3381.       if (!(REALP(z1)))
  3382.       badz1: scm_wta(z1, (char *)ARG1, sstring);
  3383. #  endif
  3384.       xy->x = REALPART(z1);}
  3385. # else
  3386.     {ASSERT(NIMP(z1) && REALP(z1), z1, ARG1, sstring);
  3387.      xy->x = REALPART(z1);}
  3388. # endif
  3389.   }
  3390.   if INUMP(z2) xy->y = INUM(z2);
  3391.   else {
  3392. # ifdef BIGDIG
  3393.     ASRTGO(NIMP(z2), badz2);
  3394.     if BIGP(z2) xy->y = scm_big2dbl(z2);
  3395.     else {
  3396. #  ifndef RECKLESS
  3397.       if (!(REALP(z2)))
  3398.       badz2: scm_wta(z2, (char *)ARG2, sstring);
  3399. #  endif
  3400.       xy->y = REALPART(z2);}
  3401. # else
  3402.     {ASSERT(NIMP(z2) && REALP(z2), z2, ARG2, sstring);
  3403.      xy->y = REALPART(z2);}
  3404. # endif
  3405.   }
  3406. }
  3407.  
  3408.  
  3409.  
  3410.  
  3411. PROC (s_sys_expt, "%expt", 2, 0, 0, scm_sys_expt);
  3412. #ifdef __STDC__
  3413. SCM
  3414. scm_sys_expt(SCM z1, SCM z2)
  3415. #else
  3416. SCM
  3417. scm_sys_expt(z1, z2)
  3418.      SCM z1;
  3419.      SCM z2;
  3420. #endif
  3421. {
  3422.   struct dpair xy;
  3423.   scm_two_doubles(z1, z2, s_sys_expt, &xy);
  3424.   return scm_makdbl(pow(xy.x, xy.y), 0.0);
  3425. }
  3426.  
  3427.  
  3428.  
  3429. PROC (s_sys_atan2, "%atan2", 2, 0, 0, scm_sys_atan2);
  3430. #ifdef __STDC__
  3431. SCM
  3432. scm_sys_atan2(SCM z1, SCM z2)
  3433. #else
  3434. SCM
  3435. scm_sys_atan2(z1, z2)
  3436.      SCM z1;
  3437.      SCM z2;
  3438. #endif
  3439. {
  3440.   struct dpair xy;
  3441.   scm_two_doubles(z1, z2, s_sys_atan2, &xy);
  3442.   return scm_makdbl(atan2(xy.x, xy.y), 0.0);
  3443. }
  3444.  
  3445.  
  3446.  
  3447. PROC (s_make_rectangular, "make-rectangular", 2, 0, 0, scm_make_rectangular);
  3448. #ifdef __STDC__
  3449. SCM
  3450. scm_make_rectangular(SCM z1, SCM z2)
  3451. #else
  3452. SCM
  3453. scm_make_rectangular(z1, z2)
  3454.      SCM z1;
  3455.      SCM z2;
  3456. #endif
  3457. {
  3458.   struct dpair xy;
  3459.   scm_two_doubles(z1, z2, s_make_rectangular, &xy);
  3460.   return scm_makdbl(xy.x, xy.y);
  3461. }
  3462.  
  3463.  
  3464.  
  3465. PROC (s_make_polar, "make-polar", 2, 0, 0, scm_make_polar);
  3466. #ifdef __STDC__
  3467. SCM
  3468. scm_make_polar(SCM z1, SCM z2)
  3469. #else
  3470. SCM
  3471. scm_make_polar(z1, z2)
  3472.      SCM z1;
  3473.      SCM z2;
  3474. #endif
  3475. {
  3476.   struct dpair xy;
  3477.   scm_two_doubles(z1, z2, s_make_polar, &xy);
  3478.   return scm_makdbl(xy.x*cos(xy.y), xy.x*sin(xy.y));
  3479. }
  3480.  
  3481.  
  3482.  
  3483.  
  3484. PROC (s_realpart, "real-part", 1, 0, 0, scm_realpart);
  3485. #ifdef __STDC__
  3486. SCM
  3487. scm_realpart(SCM z)
  3488. #else
  3489. SCM
  3490. scm_realpart(z)
  3491.      SCM z;
  3492. #endif
  3493. {
  3494.   if NINUMP(z) {
  3495. # ifdef BIGDIG
  3496.     ASRTGO(NIMP(z), badz);
  3497.     if BIGP(z) return z;
  3498. #  ifndef RECKLESS
  3499.     if (!(INEXP(z)))
  3500.     badz: scm_wta(z, (char *)ARG1, s_realpart);
  3501. #  endif
  3502. # else
  3503.     ASSERT(NIMP(z) && INEXP(z), z, ARG1, s_realpart);
  3504. # endif
  3505.     if CPLXP(z) return scm_makdbl(REAL(z), 0.0);
  3506.   }
  3507.   return z;
  3508. }
  3509.  
  3510.  
  3511.  
  3512. PROC (s_imag_part, "imag-part", 1, 0, 0, scm_imag_part);
  3513. #ifdef __STDC__
  3514. SCM
  3515. scm_imag_part(SCM z)
  3516. #else
  3517. SCM
  3518. scm_imag_part(z)
  3519.      SCM z;
  3520. #endif
  3521. {
  3522.   if INUMP(z) return INUM0;
  3523. # ifdef BIGDIG
  3524.   ASRTGO(NIMP(z), badz);
  3525.   if BIGP(z) return INUM0;
  3526. #  ifndef RECKLESS
  3527.   if (!(INEXP(z)))
  3528.   badz: scm_wta(z, (char *)ARG1, s_imag_part);
  3529. #  endif
  3530. # else
  3531.   ASSERT(NIMP(z) && INEXP(z), z, ARG1, s_imag_part);
  3532. # endif
  3533.   if CPLXP(z) return scm_makdbl(IMAG(z), 0.0);
  3534.   return flo0;
  3535. }
  3536.  
  3537.  
  3538.  
  3539. PROC (s_magnitude, "magnitude", 1, 0, 0, scm_magnitude);
  3540. #ifdef __STDC__
  3541. SCM
  3542. scm_magnitude(SCM z)
  3543. #else
  3544. SCM
  3545. scm_magnitude(z)
  3546.      SCM z;
  3547. #endif
  3548. {
  3549.   if INUMP(z) return scm_abs(z);
  3550. # ifdef BIGDIG
  3551.   ASRTGO(NIMP(z), badz);
  3552.   if BIGP(z) return scm_abs(z);
  3553. #  ifndef RECKLESS
  3554.   if (!(INEXP(z)))
  3555.   badz: scm_wta(z, (char *)ARG1, s_magnitude);
  3556. #  endif
  3557. # else
  3558.   ASSERT(NIMP(z) && INEXP(z), z, ARG1, s_magnitude);
  3559. # endif
  3560.   if CPLXP(z)
  3561.     {
  3562.       double i = IMAG(z), r = REAL(z);
  3563.       return scm_makdbl(sqrt(i*i+r*r), 0.0);
  3564.     }
  3565.   return scm_makdbl(fabs(REALPART(z)), 0.0);
  3566. }
  3567.  
  3568.  
  3569.  
  3570.  
  3571. PROC (s_angle, "angle", 1, 0, 0, scm_angle);
  3572. #ifdef __STDC__
  3573. SCM
  3574. scm_angle(SCM z)
  3575. #else
  3576. SCM
  3577. scm_angle(z)
  3578.      SCM z;
  3579. #endif
  3580. {
  3581.   double x, y = 0.0;
  3582.   if INUMP(z) {x = (z>=INUM0) ? 1.0 : -1.0; goto do_angle;}
  3583. # ifdef BIGDIG
  3584.   ASRTGO(NIMP(z), badz);
  3585.   if BIGP(z) {x = (TYP16(z)==tc16_bigpos) ? 1.0 : -1.0; goto do_angle;}
  3586. #  ifndef RECKLESS
  3587.   if (!(INEXP(z))) {
  3588.   badz: scm_wta(z, (char *)ARG1, s_angle);}
  3589. #  endif
  3590. # else
  3591.   ASSERT(NIMP(z) && INEXP(z), z, ARG1, s_angle);
  3592. # endif
  3593.   if (REALP(z))
  3594.     {
  3595.       x = REALPART(z);
  3596.       goto do_angle;
  3597.     }
  3598.   x = REAL(z); y = IMAG(z);
  3599.  do_angle:
  3600.   return scm_makdbl(atan2(y, x), 0.0);
  3601. }
  3602.  
  3603.  
  3604. PROC (s_inexact_to_exact, "inexact->exact", 1, 0, 0, scm_inexact_to_exact);
  3605. #ifdef __STDC__
  3606. SCM
  3607. scm_inexact_to_exact(SCM z)
  3608. #else
  3609. SCM
  3610. scm_inexact_to_exact(z)
  3611.      SCM z;
  3612. #endif
  3613. {
  3614.   if INUMP(z) return z;
  3615. # ifdef BIGDIG
  3616.   ASRTGO(NIMP(z), badz);
  3617.   if BIGP(z) return z;
  3618. #  ifndef RECKLESS
  3619.   if (!(REALP(z)))
  3620.   badz: scm_wta(z, (char *)ARG1, s_inexact_to_exact);
  3621. #  endif
  3622. # else
  3623.   ASSERT(NIMP(z) && REALP(z), z, ARG1, s_inexact_to_exact);
  3624. # endif
  3625. # ifdef BIGDIG
  3626.   {
  3627.     double u = floor(REALPART(z)+0.5);
  3628.     if ((u <= MOST_POSITIVE_FIXNUM) && (-u <= -MOST_NEGATIVE_FIXNUM)) {
  3629.       /* Negation is a workaround for HP700 cc bug */
  3630.       SCM ans = MAKINUM((long)u);
  3631.       if (INUM(ans)==(long)u) return ans;
  3632.     }
  3633.     ASRTGO(!IS_INF(u), badz);    /* problem? */
  3634.     return scm_dbl2big(u);
  3635.   }
  3636. # else
  3637.   return MAKINUM((long)floor(REALPART(z)+0.5));
  3638. # endif
  3639. }
  3640.  
  3641.  
  3642.  
  3643. #else                /* ~FLOATS */
  3644. PROC (s_trunc, "truncate", 1, 0, 0, scm_trunc);
  3645. #ifdef __STDC__
  3646. SCM
  3647. scm_trunc(SCM x)
  3648. #else
  3649. SCM
  3650. scm_trunc(x)
  3651.      SCM x;
  3652. #endif
  3653. {
  3654.   ASSERT(INUMP(x), x, ARG1, s_truncate);
  3655.   return x;
  3656. }
  3657.  
  3658.  
  3659.  
  3660. #endif                /* FLOATS */
  3661.  
  3662. #ifdef BIGDIG
  3663. # ifdef FLOATS
  3664. /* d must be integer */
  3665. #ifdef __STDC__
  3666. SCM
  3667. scm_dbl2big(double d)
  3668. #else
  3669. SCM
  3670. scm_dbl2big(d)
  3671.      double d;
  3672. #endif
  3673. {
  3674.   sizet i = 0;
  3675.   long c;
  3676.   BIGDIG *digits;
  3677.   SCM ans;
  3678.   double u = (d < 0)?-d:d;
  3679.   while (0 != floor(u)) {u /= BIGRAD;i++;}
  3680.   ans = scm_mkbig(i, d < 0);
  3681.   digits = BDIGITS(ans);
  3682.   while (i--) {
  3683.     u *= BIGRAD;
  3684.     c = floor(u);
  3685.     u -= c;
  3686.     digits[i] = c;
  3687.   }
  3688.   ASSERT(0==u, INUM0, OVFLOW, "dbl2big");
  3689.   return ans;
  3690. }
  3691.  
  3692.  
  3693.  
  3694. #ifdef __STDC__
  3695. double
  3696. scm_big2dbl(SCM b)
  3697. #else
  3698. double
  3699. scm_big2dbl(b)
  3700.      SCM b;
  3701. #endif
  3702. {
  3703.   double ans = 0.0;
  3704.   sizet i = NUMDIGS(b);
  3705.   BIGDIG *digits = BDIGITS(b);
  3706.   while (i--) ans = digits[i] + BIGRAD*ans;
  3707.   if (tc16_bigneg==TYP16(b)) return -ans;
  3708.   return ans;
  3709. }
  3710. # endif
  3711. #endif
  3712.  
  3713. #ifdef __STDC__
  3714. SCM
  3715. scm_long2num(long sl)
  3716. #else
  3717. SCM
  3718. scm_long2num(sl)
  3719.      long sl;
  3720. #endif
  3721. {
  3722.   if (!FIXABLE(sl)) {
  3723. #ifdef BIGDIG
  3724.     return scm_long2big(sl);
  3725. #else
  3726. # ifdef FLOATS
  3727.     return scm_makdbl((double) sl, 0.0);
  3728. # else
  3729.     return BOOL_F;
  3730. # endif
  3731. #endif
  3732.   }
  3733.   return MAKINUM(sl);
  3734. }
  3735.  
  3736.  
  3737.  
  3738. #ifdef __STDC__
  3739. SCM
  3740. scm_ulong2num(unsigned long sl)
  3741. #else
  3742. SCM
  3743. scm_ulong2num(sl)
  3744.      unsigned long sl;
  3745. #endif
  3746. {
  3747.   if (!POSFIXABLE(sl)) {
  3748. #ifdef BIGDIG
  3749.     return scm_ulong2big(sl);
  3750. #else
  3751. # ifdef FLOATS
  3752.     return scm_makdbl((double) sl, 0.0);
  3753. # else
  3754.     return BOOL_F;
  3755. # endif
  3756. #endif
  3757.   }
  3758.   return MAKINUM(sl);
  3759. }
  3760.  
  3761. #ifdef __STDC__
  3762. long
  3763. scm_num2long(SCM num, char *pos, char *s_caller)
  3764. #else
  3765. long
  3766. scm_num2long(num, pos, s_caller)
  3767.      SCM num;
  3768.      char *pos;
  3769.      char *s_caller;
  3770. #endif
  3771. {
  3772.   long res;
  3773.   if (INUMP(num))
  3774.     {
  3775.       res = INUM(num);
  3776.       return res;
  3777.     }
  3778.   ASRTGO(NIMP(num), errout);
  3779. #ifdef FLOATS
  3780.   if (REALP(num))
  3781.     {
  3782.       double u = REALPART(num);
  3783.       if ((0 <= u) && (u <= (long)~0L))
  3784.     {
  3785.       res = u;
  3786.       return res;
  3787.     }
  3788.     }
  3789. #endif
  3790. #ifdef BIGDIG
  3791.   if (BIGP(num)) {
  3792.     long oldres;
  3793.     sizet l;
  3794.     res = 0;
  3795.     oldres = 0;
  3796.     for(l = NUMDIGS(num);l--;)
  3797.       {
  3798.     res = BIGUP(res) + BDIGITS(num)[l];
  3799.     if (res < oldres)
  3800.       goto errout;
  3801.     oldres = res;
  3802.       }
  3803.     if (TYP16 (num) == tc16_bigpos)
  3804.       return res;
  3805.     else
  3806.       return -res;
  3807.   }
  3808. #endif
  3809.  errout: scm_wta(num, pos, s_caller);
  3810.   return UNSPECIFIED;
  3811. }
  3812.  
  3813.  
  3814.  
  3815.  
  3816. #ifdef __STDC__
  3817. long
  3818. num2long(SCM num, char *pos, char *s_caller)
  3819. #else
  3820. long
  3821. num2long(num, pos, s_caller)
  3822.      SCM num;
  3823.      char *pos;
  3824.      char *s_caller;
  3825. #endif
  3826. {
  3827.   long res;
  3828.   if INUMP(num) {
  3829.     res = INUM((long)num);
  3830.     return res;
  3831.   }
  3832.   ASRTGO(NIMP(num), errout);
  3833. #ifdef FLOATS
  3834.   if REALP(num) {
  3835.     double u = REALPART(num);
  3836.     if (((MOST_NEGATIVE_FIXNUM * 4) <= u)
  3837.     && (u <= (MOST_POSITIVE_FIXNUM * 4 + 3))) {
  3838.       res = u;
  3839.       return res;
  3840.     }
  3841.   }
  3842. #endif
  3843. #ifdef BIGDIG
  3844.   if BIGP(num) {
  3845.     sizet l = NUMDIGS(num);
  3846.     ASRTGO(DIGSPERLONG >= l, errout);
  3847.     res = 0;
  3848.     for(;l--;) res = BIGUP(res) + BDIGITS(num)[l];
  3849.     return res;
  3850.   }
  3851. #endif
  3852.  errout: scm_wta(num, pos, s_caller);
  3853.   return UNSPECIFIED;
  3854. }
  3855.  
  3856.  
  3857.  
  3858. #ifdef __STDC__
  3859. unsigned long
  3860. scm_num2ulong(SCM num, char *pos, char *s_caller)
  3861. #else
  3862. unsigned long
  3863. scm_num2ulong(num, pos, s_caller)
  3864.      SCM num;
  3865.      char *pos;
  3866.      char *s_caller;
  3867. #endif
  3868. {
  3869.   unsigned long res;
  3870.   if (INUMP(num))
  3871.     {
  3872.       res = INUM((unsigned long)num);
  3873.       return res;
  3874.     }
  3875.   ASRTGO(NIMP(num), errout);
  3876. #ifdef FLOATS
  3877.   if (REALP(num))
  3878.     {
  3879.       double u = REALPART(num);
  3880.       if ((0 <= u) && (u <= (unsigned long)~0L))
  3881.     {
  3882.       res = u;
  3883.       return res;
  3884.     }
  3885.     }
  3886. #endif
  3887. #ifdef BIGDIG
  3888.   if (BIGP(num)) {
  3889.     unsigned long oldres;
  3890.     sizet l;
  3891.     res = 0;
  3892.     oldres = 0;
  3893.     for(l = NUMDIGS(num);l--;)
  3894.       {
  3895.     res = BIGUP(res) + BDIGITS(num)[l];
  3896.     if (res < oldres)
  3897.       goto errout;
  3898.     oldres = res;
  3899.       }
  3900.     return res;
  3901.   }
  3902. #endif
  3903.  errout: scm_wta(num, pos, s_caller);
  3904.   return UNSPECIFIED;
  3905. }
  3906.  
  3907.  
  3908. #ifdef FLOATS
  3909. # ifndef DBL_DIG
  3910. static void add1(f, fsum)
  3911.      double f, *fsum;
  3912. {
  3913.   *fsum = f + 1.0;
  3914. }
  3915. # endif
  3916. #endif
  3917.  
  3918.  
  3919. #ifdef __STDC__
  3920. void
  3921. scm_init_numbers (void)
  3922. #else
  3923. void
  3924. scm_init_numbers ()
  3925. #endif
  3926. {
  3927. #ifdef FLOATS
  3928.   NEWCELL(flo0);
  3929. # ifdef SINGLES
  3930.   CAR(flo0) = tc_flo;
  3931.   FLO(flo0) = 0.0;
  3932. # else
  3933.   CDR(flo0) = (SCM)scm_must_malloc(1L*sizeof(double), "real");
  3934.   REAL(flo0) = 0.0;
  3935.   CAR(flo0) = tc_dblr;
  3936. # endif
  3937. # ifdef DBL_DIG
  3938.   scm_dblprec = (DBL_DIG > 20) ? 20 : DBL_DIG;
  3939. # else
  3940.   {                /* determine floating point precision */
  3941.     double f = 0.1;
  3942.     double fsum = 1.0+f;
  3943.     while (fsum != 1.0) {
  3944.       f /= 10.0;
  3945.       if (++scm_dblprec > 20) break;
  3946.       add1(f, &fsum);
  3947.     }
  3948.     scm_dblprec = scm_dblprec-1;
  3949.   }
  3950. # endif /* DBL_DIG */
  3951. #endif
  3952. #include "numbers.x"
  3953. }
  3954.  
  3955.